3

私が維持しなければならない古いアプリで法医学的考古学的調査を行っているときに、これに出くわしました:

これは、最近 .NET 4.0 に変換された WPF アプリケーションであり、このコードはバックグラウンド ワーカー内で実行されます。

           if(bgWorker1.IsBusy || bgWorker2.IsBusy)
           {
                Thread.Sleep(100); 
                Application.Current.Dispatcher.Invoke(
                    System.Windows.Threading.DispatcherPriority.Background, 
                    new System.Threading.ThreadStart(delegate { })
                );
           }

1 - no-op デリゲートを使用してスレッド (メイン GUI) を呼び出すと、どのような副作用が発生する可能性がありますか。他の 2 つのスレッドもメインの gui スレッドで呼び出しを実行しますが、優先順位を Normal 以外に設定するのはこの 1 つだけです (TreadStart ではなく Action を使用します)。

2 - このアプリケーションで奇妙なことにデッドロックに似たケースがあり、これが原因である可能性があると何かが教えてくれます。(見た目の理由もなく、優先度とメインのGUIスレッドをいじっています)。

ありがとう

4

2 に答える 2

5

このスレッドにより、ディスパッチャのスレッドが(no-op)デリゲートを「処理」できるようになるまで、呼び出し元の関数がブロックされます。

これはおそらく良い習慣ではないので、おそらく削除する必要があります。ここでの目標は、この(3番目BackgroundWorkerの)完了イベントが最初の2つが完了したときのシグナルになるようにすることだったと思いBackgroundWorkerます。

一般に、このように完成させるために回転させることは、通常、悪い設計の兆候です。はるかに優れた設計は、CountdownEventBackgroundWorkerを使用することです。これは、完了時に両方のインスタンスによって通知される可能性があります。

Thread.Sleepその後、ディスパッチャの呼び出しでループする代わりに、カウントダウンイベントを待つことができます。

于 2012-10-15T20:40:36.177 に答える
2
  1. "What possible side-effect would be acheived by [...]"使用するInvokeのでBeginInvoke、ブロックする呼び出しになります。これは、noopデリゲートが実行されるまでバックグラウンドスレッドが実行されないことを意味します。その結果、このnoopが実行される前に、メッセージループにキューに入れられたすべてのものが実行されるまで、コードは続行されません。
  2. "I have cases that strangely resembles deadlock with this application and something tells me that this could be the cause." 私にはもっともらしいように聞こえます。このコードブロックは、悪い習慣とデッドロックの可能性の両方を叫びます。コードは他のバックグラウンドワーカーを参照しているため、他の人が同様のことをしている可能性があります。

さて、何かがおかしいのは明らかなようですが、何が起こっているのかをもっと知らなければ、それをどのように修正できるかについてコメントするのはかなり難しいです。私の推測では、基本的な設計上の欠陥がありますが、採用されているアプローチです。

于 2012-10-15T20:41:28.627 に答える