我需要停止一个线程,直到另一个线程设置布尔值,并且我不想在它们之间共享事件。
我目前使用的是以下使用睡眠的代码(这是我想要更改的代码):
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中。但以下链接为根据SemaphoreSlim、AutoResetEvent和Monitor类实现的条件变量类提供了100%托管代码。它允许线程等待某个条件。并且可以在条件满足时唤醒一个或多个线程。此外,它还支持超时和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;
}
}
然后在另一个线程中,您可以唤醒一个或多个等待条件的线程。
lock(queueLock) {
//..add item here
notEmptyCondition.Pulse(); // or PulseAll
}