什么是条件变量的TPL等价物?(What is the TPL equivalent of a condition variable?)

编程入门 行业动态 更新时间:2024-10-28 18:25:47
什么是条件变量的TPL等价物?(What is the TPL equivalent of a condition variable?)

我正在学习任务并行库(与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解决方案是什么?

I'm learning the Task Parallel Library (in conjunction with C# 5.0 async/await), and I want to do something like this:

public class Foo { public void UnblockDoSomething() { DoWork(); // notify DoSomethingAsync } public async Task DoSomethingAsync() { DoSomeWork(); await ... // Wait until UnblockDoSomething is called DoMoreWork(); } }

In a traditional threaded model, I can accomplish this using condition variables. What is the TPL solution to this problem?

最满意答案

如果您只是一次一个通知,则可以使用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(); } }

如果您确实需要一个条件变量,那么可以使用AsyncEx库中的 AsyncConditionVariable :

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(); } } }

If you just have a one-at-a-time notification, you can use 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(); } }

Another option is to use a semaphore (SemaphoreSlim), which will "remember" if it's been signalled previously:

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(); } }

If you truly need a condition variable, you can use AsyncConditionVariable from my 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(); } } }

更多推荐

本文发布于:2023-07-16 06:39:00,感谢您对本站的认可!
本文链接:https://www.elefans.com/category/jswz/34/1124937.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
本文标签:等价物   变量   条件   condition   variable

发布评论

评论列表 (有 0 条评论)
草根站长

>www.elefans.com

编程频道|电子爱好者 - 技术资讯及电子产品介绍!