【问题标题】:C# async method execute base on the first completed taskC# async 方法基于第一个完成的任务执行
【发布时间】:2015-04-27 06:36:49
【问题描述】:

我有一个程序可以从位于不同物理位置的 2 个读取器读取一些值。对于一位读者,我知道我可以这样写:

private async void waitForReading()
{
    string result = await readFromReader1();    
    return result;
}

private async Task<string> readFromReader1()
{
    //poll until value detected
    return reader1Value;
}

private async Task<string> readFromReader2()
{
    //poll until value detected
    return reader2Value;
}

但是,如果我从两个阅读器中读取并在其中一个任务返回时继续执行呢?

我想要达到的效果如下:

private async void waitForReading()
{
    string result = await readFromReader1() || readFromReader2();    
    return result;
}

有可能吗?

【问题讨论】:

    标签: c# asynchronous concurrency


    【解决方案1】:

    您问题的基本答案是使用WhenAny

    var task1 = readFromReader1Async();
    var task2 = readFromReader2Async();
    return await await Task.WhenAny(task1, task2);
    

    但是,还有一些其他注意事项。

    您在实施中提到了“轮询”。如果其他阅读器已经返回了一个值,您可能希望取消这种操作。考虑使用CancellationToken 启用取消。

    考虑如何对来自“阅读器设备”的数据进行建模。如果您总是只想按需查询它们,那么async 方法就可以了。但是,如果他们的数据可以随时更改(我怀疑是这种情况),那么您可能需要考虑设置 permanent 民意调查并将其作为事件 stream;在这种情况下,响应式扩展将是更合适的模型。

    【讨论】:

    • 我的程序确实通过操作员在控制室按下按钮按需读取值,是的,我认为我需要CancellationToken,但似乎我必须使用WaitAny() 而不是@987654327 @?
    • 您不需要使用WaitAny
    • 在阅读 MSDN 上的 API 文档后,我找不到将 CancellationToken 作为参数的 WhenAny() 方法签名,请您指出如何使用带有 WhenAny() 的 CancellationToken ?
    • @OptimusFrog:你必须小心你取消的内容。将CancellationToken 传递给WaitAny 只会取消等待,而不是您的readFrom* 操作。您需要将CancellationToken 传递给readFrom*
    【解决方案2】:

    Task.WaitAny怎么样

    Task<String> task1 = readFromReader1();
    Task<String> task2 = readFromReader2();
    String result = Task.WhenAny(new Task[]{task1, task2}).Result;
    

    【讨论】:

    • 我猜Task&lt;string&gt; completedTask = Task.WhenAny(new Task[]{task1, task2}); Console.WriteLine(completedTask.Result); 可能更简单?
    【解决方案3】:

    通过研究类似的问题: Run two async tasks in parallel and collect results in .NET 4.5

    我受到bart 发布的 Task.WhenAll 方法的启发,发现 Task.WhenAny(Task[]) 正是我所需要的。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2018-05-29
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-03-15
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多