2015-04-27 25 views
2

我有一个程序可以读取位于不同物理位置的2个读取器的一些值。对于一个读者,我知道我可以像写:C#异步方法基于第一个完成的任务执行

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

这可能吗?

回答

1

如何Task.WaitAny

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

我猜 'Task completedTask = Task.WhenAny(new Task [] {task1,task2}); Console.WriteLine(completedTask.Result);' 可能更简单吗? –

+0

是的,非常感谢您指出 – huangcd

2

基本回答你的问题是使用WhenAny

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

不过,也有一些额外的考虑。

你在你的实现中提到了“轮询”。如果其他阅读器已经返回了一个值,则这种操作可能需要取消。考虑使用CancellationToken来启用取消。

想想如何对来自“读取设备”的数据建模。如果你总是只想按需求查询它们,那么async方法就没问题。但是,如果他们的数据可能随时发生变化(我怀疑是这种情况),那么您可能需要考虑设置一个永久轮询并将其作为事件消费;在这种情况下,反应式扩展将是更合适的模型。

+0

我的程序在控制室按下了一个按钮,操作员根据需要读取了值,而且我想我需要'CancellationToken',但似乎必须使用WaitAny() 'WhenAny()'? –

+0

你不需要使用'WaitAny'。 –

+0

在MSDN上阅读API文档后,我无法找到以CancellationToken作为参数的WhenAny()方法签名,您可以指示我如何使用WhenAny()的CancellationToken? –