C#异步方法基于第一个完成的任务执行

时间:2015-04-27 06:36:49

标签: c# asynchronous concurrency

我有一个程序可以读取位于不同物理位置的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;
}

有可能吗?

3 个答案:

答案 0 :(得分:2)

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

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

但是,还有一些额外的考虑因素。

您在实施中提到“轮询”。如果其他读者已经返回了值,那么您可能希望取消的操作类型。请考虑使用CancellationToken启用取消。

考虑如何为来自“读卡器设备”的数据建模。如果您总是只想按需查询它们,那么async方法就可以了。但是,如果他们的数据可以随时更改(我怀疑是这种情况),那么您可能需要考虑设置永久轮询并将其作为事件流使用;在这种情况下,Reactive Extensions将是一个更合适的模型。

答案 1 :(得分:1)

Task.WaitAny

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

答案 2 :(得分:0)

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

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