我需要停止一个线程,直到另一个线程设置一个布尔值,我不想在它们之间共享一个事件。
我目前所拥有的是使用Sleep的以下代码(这是我想要更改的代码):
while (!_engine.IsReadyToStop())
{
System.Threading.Thread.Sleep(Properties.Settings.Default.IntervalForCheckingEngine);
}
有什么想法吗?
编辑澄清事实:
我不拥有一个名为_engine的对象。我无法修改它,这就是为什么我不想在它们之间共享事件。我需要等到该类的方法返回true。
答案 0 :(得分:24)
SpinWait.SpinUntil
是正确的答案,无论您将在何处放置此代码。 SpinUntil提供"a nice mix of spinning, yielding, and sleeping in between invocations"。
答案 1 :(得分:12)
如果您使用的是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();
答案 2 :(得分:4)
声明为
AutoResetEvent _ReadyToStop = new AutoResetEvent(false);
并用作
_ReadyToStop.WaitOne();
和
_ReadyToStop.Set();
有关详细信息,请参阅Synchronization Primitives in .Net
答案 3 :(得分:0)
条件变量是可用于等待条件的同步原语。
它本身不存在于.NET中。但是,以下link为根据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
}