Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/.net/22.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 条件变量的TPL等价物是什么?_C#_.net_Asynchronous_Task Parallel Library_Async Await - Fatal编程技术网

C# 条件变量的TPL等价物是什么?

C# 条件变量的TPL等价物是什么?,c#,.net,asynchronous,task-parallel-library,async-await,C#,.net,Asynchronous,Task Parallel Library,Async Await,我正在学习任务并行库(与C#5.0异步/等待),我想做如下工作: public class Foo { public void UnblockDoSomething() { DoWork(); // notify DoSomethingAsync } public async Task DoSomethingAsync() { DoSomeWork(); await ... // Wait

我正在学习任务并行库(与C#5.0
异步
/
等待
),我想做如下工作:

public class Foo
{
    public void UnblockDoSomething()
    {
        DoWork();
        // notify DoSomethingAsync
    }

    public async Task DoSomethingAsync()
    {
        DoSomeWork();
        await ... // Wait until UnblockDoSomething is called
        DoMoreWork();
    }
}

在传统的线程模型中,我可以使用条件变量来实现这一点。这个问题的第三方物流解决方案是什么?

如果您只有一次一个通知,您可以使用
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();
  }
}
如果您确实需要条件变量,可以使用my:


要稍微扩展第一个选项,
DoSomethingAsync
可以接受表示依赖性的
Task
类型的参数。它可以等待。然后,调用方可以创建一个TCS,将相应的
任务
传递给
DoSomethingAsync
,并将TCS传递给
unbodosomething
,以允许其设置结果。
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();
  }
}
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();
    }
  }
}