子线程操作父线程

时间:2017-11-10 22:47:32

标签: multithreading powershell user-interface runspace

到目前为止,原始脚本/工具是1000多行,所以我做了一个代表我的问题的模拟。

这段代码的基本功能是创建一个带有GUI的父线程,其开始按钮创建子线程,用于复制和执行远程计算机上的文件。我希望那些子线程用结果更新父线程的文本框。在代码中,我标记了我的尝试。

我已经阅读过如何在子线程中创建GUI并通过父线程进行操作但是如果我这样做,我想我必须移动所有与GUI有关的函数和事件,到那个孩子的话题。然后“开始”按钮(子线程创建器)将创建第二代子线程?它只是把我放在一个循环中,所以我无法使用这种方法。或者我可以让Child GUI线程以某种方式启动父线程中的进程? idk ...是否可以在父线程中创建GUI的函数/事件,但是从子线程执行? IDK的...

请提供我可以考虑的任何建议或解决方案来实现这一目标。

编辑:回顾一下问题是子线程不会更新父线程文本框。

#GUI
[XML]$XAML =
@"
<Window
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    Name="Window" Title="Some tool you've never heard of" Height="450" Width="450" ResizeMode="CanMinimize">
    <Grid>
        <TextBox Name="Results" IsReadOnly="True" Margin="5,5,5,75" TextWrapping="Wrap" Background="Black" Foreground="White"/>
        <Button Name="Start" Content="Start" Margin="5,350,5,5" Cursor="Hand"/>
    </Grid>
</Window>
"@

[System.Void][System.Reflection.Assembly]::LoadWithPartialName('presentationframework')

$GUI = [Windows.Markup.XamlReader]::Load((New-Object System.Xml.XmlNodeReader $XAML))

ForEach ($Node in ($XAML.SelectNodes("//*[@Name]")))
{
    Set-Variable -Name "$($Node.Name)" -Value $GUI.FindName($Node.Name) -Scope Global
}

#Sync Hash Table - Attempt 2
$Global:SyncUIHash = [hashtable]::Synchronized(@{})
$Global:SyncUIHash.Window = $Window
$Global:SyncUIHash.Results = $Results

#RunSpacePool
$RunSpacePool = [RunSpaceFactory]::CreateRunspacePool(1,5)
$RunSpacePool.ApartmentState = "STA"
$RunSpacePool.Open()

#GUI Events
$Start.Add_Click({Start-Function})

#Functions
Function Start-Function
{
    ($PowerShell = [Powershell]::Create()).RunSpacePool = $RunspacePool

    $Parameters = @{
        Computer = "ComputerName"
        FileToExecute = "FilePath to file that will be executed"
        Arguments = "Arguments to be used on FileToExecute"
        TempDir = "Remote Computer's TempDir to Copy To"
        Results = $Results #Does not Work - Attempt 1
        SyncUIHash = $Global:SyncUIHash #Does not work - Attempt 3
    }

    [System.Void]$PowerShell.AddScript({
        Param (
            $Computer,
            $FileToExecute,
            $Arguments,
            $TempDir,
            $Results, #Does not work - Attempt 1
            $SyncUIHash #Does not work - Attempt 3
        )
        #Basically: Copy File to Remote Computer then Execute File

        $Results.Text += "Results of whole process." #Does not work - Attempt 1

        $SyncUIHash.Results.Text += "Results of whole process." # Does not work - Attempt 2 & 3

    }).AddParameters($Parameters)

    $PowerShell.BeginInvoke()
}

#Shows GUI
[System.Void] $GUI.ShowDialog()

0 个答案:

没有答案