Multithreading 子线程操作父线程

Multithreading 子线程操作父线程,multithreading,powershell,user-interface,runspace,Multithreading,Powershell,User Interface,Runspace,到目前为止,最初的脚本/工具有1000多行,所以我做了一个模拟来表示我的问题 这段代码基本上是用GUI创建一个父线程,它的“开始”按钮创建复制和执行远程计算机上文件的子线程。我希望这些子线程用结果更新父线程的文本框。在代码中,我标记了我的尝试 我读过关于在子线程中创建GUI并通过父线程对其进行操作的内容,但如果要这样做,我想我必须将所有与GUI相关的函数和事件移动到该子线程。然后开始按钮(子线程创建者)将创建第二代子线程?这让我陷入了一个循环,所以我无法使用这种方法。或者我可以让子GUI线程以某

到目前为止,最初的脚本/工具有1000多行,所以我做了一个模拟来表示我的问题

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

我读过关于在子线程中创建GUI并通过父线程对其进行操作的内容,但如果要这样做,我想我必须将所有与GUI相关的函数和事件移动到该子线程。然后开始按钮(子线程创建者)将创建第二代子线程?这让我陷入了一个循环,所以我无法使用这种方法。或者我可以让子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()
#GUI
[XML]$XAML=
@"
"@
[System.Void][System.Reflection.Assembly]::LoadWithPartialName('presentationframework'))
$GUI=[Windows.Markup.XamlReader]::加载((New Object System.Xml.XmlNodeReader$XAML))
ForEach($XAML.SelectNodes(“//*[@Name]”)中的节点)
{
设置变量-名称“$($Node.Name)”-值$GUI.FindName($Node.Name)-作用域全局
}
#同步哈希表-尝试2
$Global:SyncUIHash=[hashtable]::Synchronized(@{})
$Global:SyncUIHash.Window=$Window
$Global:SyncUIHash.Results=$Results
#运行空间池
$RunSpacePool=[RunSpaceFactory]::CreateRunspacePool(1,5)
$RunSpacePool.ApartmentState=“STA”
$RunSpacePool.Open()
#GUI事件
$Start.Add_单击({Start Function})
#功能
函数启动函数
{
($PowerShell=[PowerShell]::Create()).RunSpacePool=$RunSpacePool
$Parameters=@{
Computer=“ComputerName”
FileToExecute=“将要执行的文件的文件路径”
Arguments=“要在FileToExecute上使用的参数”
TempDir=“要复制到的远程计算机的TempDir”
结果=$Results#不起作用-尝试1
SyncUIHash=$Global:SyncUIHash#不工作-尝试3
}
[System.Void]$PowerShell.AddScript({
Param(
$Computer,
$FileToExecute,
$Arguments,
$TempDir,
$Results,#不起作用-尝试1
$SyncUIHash#不起作用-尝试3
)
#基本上:将文件复制到远程计算机,然后执行文件
$Results.Text+=“整个过程的结果。”#不起作用-尝试1
$SyncUIHash.Results.Text+=“整个过程的结果。”#不起作用-尝试2和3
}).AddParameters($Parameters)
$PowerShell.BeginInvoke()
}
#显示图形用户界面
[System.Void]$GUI.ShowDialog()

你能详细说明你的问题吗。什么不起作用?您提供的一些代码似乎有问题,但您没有描述问题。问题是子线程基本上不更新父线程文本框。主帖子也已经更新了。不可能从任何其他线程更新一个线程持有的GUI对象。这是通过设计来避免许多固有的问题。但是,您仍然可以从任何线程访问这些GUI对象。要更新它们,您需要将控制权恢复到父线程,并让父线程更新GUI。@Rohindharth无法从任何其他线程更新一个线程持有的GUI对象。管道和事件是什么?当然,它实际上不是由另一个线程更新的,但它是由它们发起的。请看以下内容: