0

TPL を新しいアプリケーション (.Net Framework 4.0 を使用) に使用するつもりなので、TPL で脳を更新するのに忙しくしています。しかし、誰かが私のために明確にするかもしれないという疑問があります。以前は、進行状況を表示する必要があるスレッドを開始した後、メイン (GUI) スレッドから起動する進行状況フォームがありました。それは次のように見えました:

sortThread = New Thread(AddressOf _Sorter.Sort())
_ProgressForm = New FrmProgress()
_Sorter.ProgressForm = _ProgressForm
sortThread.Start()
progressForm.ShowDialog()

基本的には、スレッドを初期化し、FrmProgress フォーム オブジェクトを初期化し、それを Sorter オブジェクトに割り当てて、別のスレッドの Sort() サブルーチンから進行状況フォーム (進行状況バーといくつかのラベルを含む) を更新します。これらのコントロール プロパティの更新は、FrmProgress フォームの InvokeRequired プロパティをチェックすることによって達成され、必要に応じて、更新されるコントロールの Invoke() メソッドを使用します...例:

Public Sub IncrementProgressBar(x As Integer)
   If Me.InvokeRequired Then
      pb_MainProgressBar.Invoke(Sub() IncrementProgressBar(x))
   Else
      pb_MainProgressBar.Increment(x)
   End If    
End Sub

現在、TPL を使用して、プログレス バーを更新する可能性のある個別のワーカー スレッド (複数) を起動することに興味があります。同じパターンを使用する必要がありますか、それともメイン GUI スレッドで取得されたパブリック TaskScheduler.FromCurrentSynchronizationContext コンテキストへのアクセスを検討する必要がありますか? どちらの場合も、フォームに何らかのロック メカニズムを提供する必要があると思います (SyncLock?)

4

1 に答える 1

1

あなたがしているように、呼び出しで十分なはずです。2 つの異なるスレッドが並行して呼び出そうとすると、最初のスレッドが最初に実行され、次に UI スレッドが解放されたときに 2 番目のスレッドが実行されます。UI スレッドは 2 つの呼び出しを同時に処理することはできません。それらは当然 FIFO シーケンスで処理されるため、スレッド セーフの問題はありません。メインスレッド上で任意の数のスレッドを呼び出すことができ、相互に心配したり、追加のロックメカニズムを使用したりする必要はありません。

ただし、スレッドInvokeの呼び出しは、メイン スレッドが呼び出しを処理できるようになるまでブロックされることに注意してください。たとえば、大量のコードを同時に呼び出すスレッドが多数ある場合、さまざまなスレッドは、いわば、缶でキックが得られるまで、invoke 呼び出しでブロックされます。を使用するBeginInvokeと、呼び出し元のスレッドは単に実行を継続し、呼び出されたメソッドは UI スレッドのキューに配置されます (可能な限りすぐにサービスを提供します)。

于 2013-06-07T18:31:10.257 に答える