C#异步方法基于第一个完成的任务执行
C# async method execute base on the first completed task
我有一个程序可以从位于不同物理位置的 2 reader 中读取一些值。对于一个 reader 我知道我可以这样写:
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;
}
但是,如果我从两个 reader 中读取并在其中一个任务返回时继续执行怎么办?
我想达到的效果是这样的:
private async void waitForReading()
{
string result = await readFromReader1() || readFromReader2();
return result;
}
可能吗?
通过调查类似的问题:
Run two async tasks in parallel and collect results in .NET 4.5
我受到 bart 发布的 Task.WhenAll 方法的启发,发现 Task.WhenAny(Task[]) 是我需要的。
怎么样Task.WaitAny
Task<String> task1 = readFromReader1();
Task<String> task2 = readFromReader2();
String result = Task.WhenAny(new Task[]{task1, task2}).Result;
您问题的基本答案是使用 WhenAny
:
var task1 = readFromReader1Async();
var task2 = readFromReader2Async();
return await await Task.WhenAny(task1, task2);
但是,还有一些其他注意事项。
您在实施中提到了 "polling"。如果另一个 reader 已经返回值,您可能希望 取消 这种操作。考虑使用 CancellationToken
启用取消。
考虑如何对来自 "reader devices" 的数据建模。如果您总是只想按需查询它们,那么 async
方法就可以了。但是,如果他们的数据可以随时更改(我怀疑是这种情况),那么您可能需要考虑设置一个 permanent 轮询并将其作为事件使用 流;在这种情况下,Reactive Extensions 将是更合适的模型。
我有一个程序可以从位于不同物理位置的 2 reader 中读取一些值。对于一个 reader 我知道我可以这样写:
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;
}
但是,如果我从两个 reader 中读取并在其中一个任务返回时继续执行怎么办?
我想达到的效果是这样的:
private async void waitForReading()
{
string result = await readFromReader1() || readFromReader2();
return result;
}
可能吗?
通过调查类似的问题: Run two async tasks in parallel and collect results in .NET 4.5
我受到 bart 发布的 Task.WhenAll 方法的启发,发现 Task.WhenAny(Task[]) 是我需要的。
怎么样Task.WaitAny
Task<String> task1 = readFromReader1();
Task<String> task2 = readFromReader2();
String result = Task.WhenAny(new Task[]{task1, task2}).Result;
您问题的基本答案是使用 WhenAny
:
var task1 = readFromReader1Async();
var task2 = readFromReader2Async();
return await await Task.WhenAny(task1, task2);
但是,还有一些其他注意事项。
您在实施中提到了 "polling"。如果另一个 reader 已经返回值,您可能希望 取消 这种操作。考虑使用 CancellationToken
启用取消。
考虑如何对来自 "reader devices" 的数据建模。如果您总是只想按需查询它们,那么 async
方法就可以了。但是,如果他们的数据可以随时更改(我怀疑是这种情况),那么您可能需要考虑设置一个 permanent 轮询并将其作为事件使用 流;在这种情况下,Reactive Extensions 将是更合适的模型。