我正在学习任务并行库(结合 C# 5.0 async
/await
),我想做这样的事情:
public class Foo
{
public void UnblockDoSomething()
{
DoWork();
// notify DoSomethingAsync
}
public async Task DoSomethingAsync()
{
DoSomeWork();
await ... // Wait until UnblockDoSomething is called
DoMoreWork();
}
}
在传统的线程模型中,我可以使用条件变量来完成此操作。这个问题的 TPL 解决方案是什么?
最佳答案
如果你只有一次一个通知,你可以使用TaskCompletionSource
:
public class Foo
{
private TaskCompletionSource<object> _signal = new TaskCompletionSource<object>();
public void UnblockDoSomething()
{
DoWork();
_signal.SetResult(null);
_signal = new TaskCompletionSource<object>();
}
public async Task DoSomethingAsync()
{
var continueSignal = _signal.Task;
DoSomeWork();
await continueSignal;
DoMoreWork();
}
}
另一种选择是使用信号量 (SemaphoreSlim
),如果之前收到过信号,它将“记住”:
public class Foo
{
private readonly SemaphoreSlim _mutex = new SemaphoreSlim(0);
public void UnblockDoSomething()
{
DoWork();
_mutex.Release();
}
public async Task DoSomethingAsync()
{
DoSomeWork();
await _mutex.WaitAsync();
DoMoreWork();
}
}
如果你真的需要一个条件变量,你可以使用AsyncConditionVariable
来 self 的 AsyncEx library :
public class Foo
{
private readonly AsyncLock _mutex = new AsyncLock();
private readonly AsyncConditionVariable _cv = new AsyncConditionVariable(_mutex);
public void UnblockDoSomething()
{
using (await _mutex.LockAsync())
{
DoWork();
_cv.Notify();
}
}
public async Task DoSomethingAsync()
{
using (await _mutex.LockAsync())
{
DoSomeWork();
await _cv.WaitAsync();
DoMoreWork();
}
}
}
关于c# - 条件变量的 TPL 等价物是什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16656538/