Я пытаюсь узнать, как использовать Runspace для передачи значений в графический интерфейс. Я подкорректировал сценарий, написанный Boe Prox, пытаясь понять, как Dispatcher.Invoke работает с и пространством выполнения попался очень странная проблемойИспользование Dispatcher Invoke с Runspace в Powershell
$uiHash = [hashtable]::Synchronized(@{})
$newRunspace =[runspacefactory]::CreateRunspace()
$newRunspace.ApartmentState = "STA"
$newRunspace.ThreadOptions = "ReuseThread"
$newRunspace.Open()
$newRunspace.SessionStateProxy.SetVariable("uiHash",$uiHash)
$psCmd = [PowerShell]::Create().AddScript({
$uiHash.Error = $Error
[xml]$xaml = @"
<Window
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
x:Name="Window" Title="Initial Window" WindowStartupLocation = "CenterScreen"
Width = "650" Height = "800" ShowInTaskbar = "True">
<TextBox x:Name = "textbox" Height = "400" Width = "600"/>
</Window>
"@
$reader=(New-Object System.Xml.XmlNodeReader $xaml)
$uiHash.Window=[Windows.Markup.XamlReader]::Load($reader)
$uiHash.TextBox = $uiHash.window.FindName("textbox")
$uiHash.Window.ShowDialog() | Out-Null
})
$psCmd.Runspace = $newRunspace
$handle = $psCmd.BeginInvoke()
#-----------------------------------------
#Using the Dispatcher to send data from another thread to UI thread
Update-Window -Title ("Services on {0}" -f $Env:Computername)
$uiHash.Window.Dispatcher.invoke("Normal",[action]{$uiHash.TextBox.AppendText('test')})
Если бы я должен был использовать последнюю строку скрипта без Update-Window -Title ("Services on {0}" -f $Env:Computername)
Я получаю ошибку you cannot call a method on a null-valued expression.
InvokeMethodOnNull, и текст не добавляется. Однако, если я добавлю Update-Window -Title ("Services on {0}" -f $Env:Computername)
прямо над линией Dispatcher.invoke, я все равно получаю ошибку, но текстовое поле содержит прилагаемый текст.
В чем причина этого события? Я пробовал так много способов использовать Dispatcher.Invoke для добавления контента в текстовые поля, но всегда заканчивается ошибкой cannot call a method method on null
без каких-либо успехов, но теперь добавление некоторых строк, ссылающихся на пользовательский интерфейс и вызывающих Dispatcher.Invoke, похоже, заставляет его работать.
Благодарим вас за это разъяснение. Выполняет ли сценарий через консоль vs Powershell ISE какое-либо значение с точки зрения многопоточности? Будет ли ваш сценарий написан по-другому, если вы хотите развернуть его через консоль? – Bregs