短時間のバーストでアクティブになり、残りの時間はアイドル状態になる可能性のあるワーカースレッドがあります。スレッドをスリープ状態にして、必要に応じてスリープ解除することを考えています。
これに関する追加の推奨事項について知っておく必要がありますか?
ありがとう!
- これはC#/。NET4にあります
短時間のバーストでアクティブになり、残りの時間はアイドル状態になる可能性のあるワーカースレッドがあります。スレッドをスリープ状態にして、必要に応じてスリープ解除することを考えています。
これに関する追加の推奨事項について知っておく必要がありますか?
ありがとう!
おそらく、永続的なワーカー スレッドを使用するべきではありません。スレッド プールを使用してください。これはまさにそれが意図したものです。
ThreadPool.QueueUserWorkItem(() => {
// My temporary work here
});
永続的なワーカー スレッドが必要な場合は、次のように実行します。
// This is our latch- we can use this to "let the thread out of the gate"
AutoResetEvent threadLatch = new AutoResetEvent(false);
// The thread runs this
public void DoBackgroundWork() {
// Making sure that the thread is a background thread
// ensures that the endless loop below doesn't prevent
// the program from exiting
Thread.IsBackground = true;
while (true) {
// The worker thread will get here and then block
// until someone Set()s the latch:
threadLatch.WaitOne();
// Do your work here
}
}
// To signal the thread to start:
threadLatch.Set();
また、このバックグラウンド スレッドがユーザー インターフェイスとやり取りする場合は、それに応じて Invoke または BeginInvoke する必要があることに注意してください。http://weblogs.asp.net/justin_rogers/pages/126345.aspxを参照してください。
イベントを使用してワーカー スレッドを一時停止するだけです: リセット - 一時停止、設定 - 一時停止解除 (作業) 状態。
このアプローチを示すコードのドラフトバージョンを次に示します。
class Worker
{
private Thread _thread;
// Un-paused by default.
private ManualResetEvent _notToBePaused = new ManualResetEvent(true);
public Worker()
{
_thread = new Thread(Run)
{
IsBackground = true
};
}
/// <summary>
/// Thread function.
/// </summary>
private void Run()
{
while (true)
{
// Would block if paused!
_notToBePaused.WaitOne();
// Process some stuff here.
}
}
public void Start()
{
_thread.Start();
}
public void Pause()
{
_notToBePaused.Reset();
}
public void UnPause()
{
_notToBePaused.Set();
}
}
WaitHandle によるシグナリングは正しい方法ですが、他の人が既に言ったことを追加するだけです
私は通常、2 つのシグナルを一緒に使用します。そうしないと、必要に応じて「続行」するか「終了」するかがわからないか、またはそれを行うためのあまり優雅でない方法 (スレッドを停止する - もちろんあります) に頼る必要があります。このようなことを行う他の方法がありますが、1 つの「パターン」にすぎません)。したがって、通常は「終了」シグナルと「新しい作品が利用可能」シグナルで動作し、同時に動作します。例えば
WaitHandle[] eventArray = new WaitHandle[2] { _exitEvent, _newWorkEvent };
while ((waitid = WaitHandle.WaitAny(eventArray, timeout, false)) > 1)
{
// do your work, and optionally handle timeout etc.
}
注:
exit はManualResetEvent
「false」の初期状態であり、「Set」イベントを終了します。その場合、外部から一時停止/続行する必要がある
_newWork
かのどちらかです
。作業の「新しいバッチ」ごとにそれを繰り返す必要があります - これは少し単純化されています。(多くの場合、いくつかの「メッセージ」が渡され、もちろん何らかの方法で同期されます)。 Manual
new AutoResetEvent(false)
これにより、さらに情報が追加されることを願っています。