2011-01-21 11 views

答えて

7

BackgroundWorkerは、機能するために設定されている現在のSynchronizationContextに依存しています。実際には、UIコードを扱うためのものです。

UI同期の問題がないため、通常はサービスで自己のスレッドを自己管理する方が良いです。スレッドAPI(または.NET 4タスクAPI)を使用する方がはるかに優れたオプションです。

+0

ありがとう、リード。私はそれがUIコードのためだけに使用されるべきだと読んだことがあります。私はサービスでそれを使用することはありませんが、オフィスでは「危機」を起こしています。もの。私は彼らに問題についての独立した見解を与えたいと思っていました。 –

+1

彼の "危機"を解決するOtavioの能力を向上させること、そして私たちの養成 - * Why *はなぜThreading/Task API> BackgroundWorkerをサービスに利用するか? C.ローレンスは悪影響を報告していません。どのような悪影響が可能ですか? –

+1

@djacobson:問題のサービスに依存します。同期コンテキストが存在しない場合、BWは余分なオーバーヘッドを追加するだけで、メリットはありません。 WCFなどのSCを持つサービスでこのサービスを使用している場合、期待どおり機能しますが、実際はまだかなり不必要です。あなたのDoWorkメソッドを呼び出すのが簡単で、必要に応じて他のメソッドを呼び出せます。 –

1

私はWindowsサービスで何度も悪影響を及ぼすことなくBackgroundWorkerを使用しました。 SynchronizationContextを使用する必要はないかもしれませんが、問題が発生したりパフォーマンスが低下することはありません。

2

サービスでBGWを使用するのは大丈夫ですが、特に便利なことはありません。その理由は、特定のスレッドでProgressChangedイベントとRunWorkerCompletedイベントを発生させるためです。 特定のスレッドで実行するコードを取得することは、非常に簡単なことです。コードを実行している間は、単にスレッドに呼び出しを挿入することはできません。それは恐ろしい再突入問題を引き起こす。インジェクションコードが問題を起こさない状態で、スレッドは「アイドル」でなければなりません。

スレッドがアイドル状態にあることは、非常に不自然な状態です。 にスレッドを使用してコードを実行します。そのスレッドが空転しているとは限りません。しかし、これはUIスレッドの仕組みです。メッセージループに時間の99%を費やし、Windowsが何かをするようにWindowsを待っています。ボタンクリック、ペイントリクエスト、キーボードプレス、そのようなもの。メッセージループ内にある間は、実際にはアイドル状態です。注入されたコードを実行するのに非常に良い時期です。

WinformsのControl.Begin/InvokeとWPFのDispatcher.Begin/Invokeは何をしていますか?デリゲートをキューに入れ、キューを空にして、デリゲートターゲットをメッセージループで実行します。 WindowsFormsSynchronizationContextクラスとDispatcherSynchronizationContextクラスは、それらを使用する同期プロバイダです。 WinformsとWPFはSynchronizationContext.Currentをそのインスタンスに置き換えます。これはイベントを起こすためにBGWによって使用されます。これはUIスレッド上で実行されます。これにより、スレッドセーフではないユーザーインターフェイスコンポーネントをワーカースレッドから更新できます。

これはどこにあるのか分かりますが、サービスではどちらも使用されていません。デフォルトの同期プロバイダは何も同期しません。スレッドプールスレッドを使用してSendまたはPostコールバックを呼び出します。 BGWをサービスで使用すると、どのようなことが起こりますか。今、これらの出来事を持つことには、実際には何のポイントもありません。 DoWorkハンドラにイベント処理メソッドを直接呼び出させることもできます。結局のところ、DoWorkを実行するスレッドは別のスレッドプールスレッドにすぎません。

まあ、実際の害はありません。かなり遅くなります。

関連する問題