別のスレッドがブール値を設定するまでスレッドを停止する必要がありますそして、それらの間でイベントを共有したくない。
私が現在持っているのは、Sleepを使用した次のコードです(これが変更したいコードです)。
while (!_engine.IsReadyToStop())
{
System.Threading.Thread.Sleep(Properties.Settings.Default.IntervalForCheckingEngine);
}
何か案は?
説明を明確にするために編集:
私が所有していないクラスの_engineというオブジェクトがあります。私はそれを修正することはできません、それが私が彼らの間でイベントを共有したくない理由です。そのクラスのメソッドがtrueを返すまで待つ必要があります。
SpinWait.SpinUntil
が正しい答えです。このコードをどこに配置するかは関係ありません。 SpinUntilは "呼び出し間での回転、制御、スリープの素晴らしい組み合わせ" を提供します。
C# 4.0
を使用している場合は、以下を使用できます。
Task t = Task.Factory.StartNew (() => SomeCall(..));
t.Wait();
Task.Wait メソッドを使用する。
複数のタスクを次々に実行する場合は、 Task.ContinueWith を使用できます。
Task t = Task.Factory.StartNew (() =>SomeCall(..)).
ContinueWith(ExecuteAfterThisTaskFinishes(...);
t.Wait();
宣言する
AutoResetEvent _ReadyToStop = new AutoResetEvent(false);
そしてとして使用
_ReadyToStop.WaitOne();
そして
_ReadyToStop.Set();
詳細は 。Netの同期プリミティブ を参照してください
条件変数は、条件を待機するために使用できる同期プリミティブです。
.NETにはネイティブには存在しません。ただし、次の link は、SemaphoreSlim、AutoResetEvent、およびMonitorクラスに関して実装された条件変数クラスに100%マネージコードを提供します。これにより、スレッドは条件を待機できます。また、条件が満たされたときに1つ以上のスレッドを起動できます。さらに、タイムアウトとCancellationTokensをサポートします。
ある条件で待機するには、次のようなコードを記述します。
object queueLock = new object();
ConditionVariable notEmptyCondition = new ConditionVariable();
T Take() {
lock(queueLock) {
while(queue.Count == 0) {
// wait for queue to be not empty
notEmptyCondition.Wait(queueLock);
}
T item = queue.Dequeue();
if(queue.Count < 100) {
// notify producer queue not full anymore
notFullCondition.Pulse();
}
return item;
}
}
次に、別のスレッドで、条件待ちの1つ以上のスレッドをウェイクアップできます。
lock(queueLock) {
//..add item here
notEmptyCondition.Pulse(); // or PulseAll
}