2

I have a program that will read some values from 2 readers located at different physical locations. For one reader I know I can write like:

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

However, what if I read from two readers and resume execution when one of the task returned?

What I want to achieve looks like:

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

Is it possible?

3 Answers 3

2

The basic answer to your question is to use WhenAny:

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

However, there are a few additional considerations.

You mention "polling" in your implementation. This is the kind of operation that you'd probably want to cancel if the other reader has already returned a value. Consider using CancellationToken to enable cancellation.

Think about how to model the data coming from your "reader devices". If you always just want to query them on demand, then an async approach is fine. However, if their data can change at any time (which I suspect is the case), then you might want to consider setting up a permanent poll and consume it as an event stream; in this case, Reactive Extensions would be a more appropriate model.

Sign up to request clarification or add additional context in comments.

4 Comments

my program did read values on demand by an operator pressing a button in control room, and yes I think I need the CancellationToken, but it seems I have to use WaitAny() instead of WhenAny()?
You shouldn't need to use WaitAny.
After reading the API doc on MSDN, I can't find a method signature of WhenAny() that takes a CancellationToken as parameter, may you point me how to make use of a CancellationToken with WhenAny()?
@OptimusFrog: You have to be careful what you're cancelling. Passing a CancellationToken to WaitAny will only cancel the wait, not your readFrom* operations. You need to pass a CancellationToken into readFrom*.
1

How about Task.WaitAny

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

1 Comment

I guess Task<string> completedTask = Task.WhenAny(new Task[]{task1, task2}); Console.WriteLine(completedTask.Result); is more simple maybe?
0

By looking into a similar question: Run two async tasks in parallel and collect results in .NET 4.5

I get inspired by Task.WhenAll method posted by bart, and find that Task.WhenAny(Task[]) is what I need.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.