9

開発中のアプリケーションで .NET Backgroundworker オブジェクトを使用しようとしています。

インターネット上のすべての資料は、このオブジェクトが「バックグラウンド」で実行されると述べていますが、このバックグラウンド スレッドが実際に「低優先度」モードで実行されていることを確認できた場所はありません。この疑問が生じるのは、Windows (私が推測する) では、バックグラウンド タスクが「通常」または「通常以下」または「低」の優先度モードで実行される可能性があるためです。

私のアプリケーションでは、DoWork 関数内で自分で優先順位を設定しようとしました...

Thread.CurrentThread.Priority=ThreadPriority.Lowest

...

しかし、これは効果がないようです。バックグラウンドワーカーはこの呼び出しを無視しますか?

もう少し説明したいと思います:

私のアプリケーションは、チャンバーから温度、湿度などのリアルタイム データを収集し、使用して Web ページ (Web サービスではない) にアップロードするインターネット クライアントです。

system.net.webclient.UploadValuesAsync(...)通話

クライアント GUI がチャンバーからデータを収集し、タイムスタンプを付けて、アップロードのためにキューに入れるように、アプリケーションを作成しました。

...

Synclock objlock
    debug.print("Queueing reading...")
    dataQ.Enque(reading)
End Synclock
...

バックグラウンドワーカーの Dowork 関数は、デキューしてからアップロードします...

…………

Do
        if dataQ.count() <> 0 then
            Synclock objlock
              reading = dataQ.DeQue()
            End Synclock
            Dim client As New System.Net.WebClient
            ...put the reading in NameValueCollection and upload to server page
            req = new NameValueCollection
            ...
            ...
            client.UploadValuesAsync(uri, "POST", req)
        endif
        thread.sleep(1) 'without this line the CPU usage goes upto 100% and seems to slow other tasks!
    Loop

...............

プログラムを実行すると、UploadValuesAsync が呼び出されて出力されるたびに、デバッグ ウィンドウが停止することがわかりました。また、デバッグ ステートメントを追加して、キューにある読み取り値の数をいつでも確認できるようにしました。このタスクが本当に低い優先度で実行されている場合、データが取得されるとキューの数が急速に増加し、フォアグラウンドがアイドル状態でデータが取得されていないときにのみ減少することが予想されました。しかし、そうではありません。読み取り値がキューに追加されるとすぐに、キューから取り出されてアップロードされます。したがって、キュー カウントは常に 1 または 0 です。

私のアプローチに何か問題がありますか?background-worker オブジェクトをまったく使用しないでください。

ところで、これは Windows XP を実行しているデュアルコア ラップトップです。

4

4 に答える 4

16

ジョンとマークがすでに言ったことに追加するだけです:

バックグラウンド スレッドの優先度が低くなることはありません。フォアグラウンド スレッドとバックグラウンド スレッドの違いは、実行中のフォアグラウンド スレッドがなくなると CLR がプロセスをシャットダウンすることです。スレッド プール スレッドはバックグラウンド スレッドです。

実際にスレッド プール スレッドの優先度を設定することはできますが、どのスレッド プール スレッドが実際にタスクを実行するかをほとんど制御できないため、設定することはお勧めできません。特定の優先度のスレッドが必要な場合は、Thread タイプを使用してスレッドを作成し、必要に応じてインスタンスの優先度を設定する必要があります。

于 2009-02-07T20:53:08.173 に答える
8

はい、あなたのアプローチに何か問題があります.キューが空のときは基本的にタイトループです. スレッドの優先順位がどうであれ、それは悪い考えです。

これにバックグラウンドワーカーを使用しても問題はありませんが、エンキュー/デキューでは、準備ができていないときにデキューしようとするとブロックされるプロデューサー/コンシューマーキューを使用する必要があります。

スレッド チュートリアルにプロデューサー/コンシューマー キューの実装例があります。リンクされたページの約半分を参照してください。ところで、キューからの取り出しプロセスが終了したことを伝える何らかの方法が必要になるでしょう。(たとえば、null 参照またはその他の特別な値をキューに入れる。) そのコードはジェネリック以前に作成されたものですが、簡単に更新できるはずです。

于 2009-02-07T20:19:06.323 に答える
3

優先度が低いとは主張していません。バックグラウンドとは、a: UI スレッドではなく、b: プロセスを存続させないことを意味します。実際には、おそらくThreadPoolスレッドに関連しています。

特定の優先度のスレッドが必要な場合は、独自のThreadオブジェクトを使用しますが、通常はこれもお勧めしません...

さらに、「バックグラウンド」は「アイドル時」を意味するものではありません。シングル コア マシンでも、おそらく両方のスレッドが同じくらい多くの rnutime を取得することがわかります (必要な場合)。マルチコアではなおさらです。

于 2009-02-07T20:18:44.000 に答える
1

このワーカー スレッドの実装を確認することをお勧めします。スレッドの名前、スレッドの優先順位、およびスレッドがバックグラウンド スレッドであるかどうかを指定するためのプロテクト コンストラクターがあります。

http://devpinoy.org/blogs/jakelite/archive/2008/12/20/threading-patterns-the-worker-thread-pattern.aspx

于 2009-02-09T17:12:44.867 に答える