編集:サンプルコードは元の目標からはほど遠いですが、私が実際に提起した質問に対する正当な答えがあるので、質問とタイトルを編集しました。
WinForms GUIを使用してマルチスレッドPowerShellスクリプトを作成していますが、スクリプト内の他のスレッドの1つからGUIを更新したいと思います。私はこれをするのにまったく運がありません。実際、私は仕事に就くことさえできませんBeginInvoke
。
これは非常に簡略化された例です。これはサンプルコードであり、本番環境ではないため、きれいではありませんが、問題を再現しています。
$script:SynchronizedUIHash = [Hashtable]::Synchronized(@{});
[reflection.assembly]::LoadWithPartialName( "System.Windows.Forms")
$form= New-Object Windows.Forms.Form
$label = New-Object Windows.Forms.Label
$label.Text = 'original'
$script:SynchronizedUIHash.label = $label
$form.Controls.add($label)
$form.show()
[System.Windows.Forms.Application]::DoEvents()
Read-Host
$label.BeginInvoke(
[Action[string]] {
param($Message)
[Console]::Beep(500,300)
$l = $SynchronizedUIHash.label
$l.Text = $Message
[System.Windows.Forms.Application]::DoEvents()
},
'changed'
)
Read-Host
$form.close()
コンソールのビープ音すら聞こえないので、BeginInvoke
コードがまったく実行されていないようです。
[System.Windows.Forms.Application]::DoEvents()
その後にスローインするとRead-Host
、変化が見られるのでタイミングの問題のようですが、スピンループなどのばかげたものにはなりたくありません-ファイアアンドフォーゲットしBeginInvoke
て結果を出したい必要に応じて表示されます。PowerShellに対するもののような他の回答が表示されます:フォームが実行されていないジョブイベントアクションですが、チェック、スリープ、チェックループにある必要があります。
私が行方不明になっているより簡単な方法がなければなりません...それは何ですか?
ここでの正しい解決策は何ですか?
編集:キースのコメントは、私が本番からストリップされたサンプルコードに移行する重要なポイントを逃したことに気づきました-ジョブの起動は確かにマルチプロセスですが、サンプルコードはそうではないので、サンプルは実際の生活を反映していません、そして私は全体を考え直す必要があります。とはいえ、サンプルコードはジョブを使用せず、期待どおりに機能しないため、この特定のケースでは役に立たない場合でも、その理由を理解したいと思います。