I'm attempting to create an async method which returns data from an event, or times out (and returns null). The code below loosely follows suggestions from other threads.
public async Task<Data> GetNextData(TimeSpan timeout)
{
var tcs = new TaskCompletionSource<Data>();
//setup event handler
var onEvent = new EventHandler<Data>((sender, args) =>
{
tcs.SetResult(args);
});
OnDataReceived += onEvent;
//await result from handler or timeout
Data result = null;
if (await AwaitWithTimeout(tcs.Task, timeout))
{
result = tcs.Task.Result;
}
//cleanup
OnDataReceived -= onEvent;
return result;
}
private static async Task<bool> AwaitWithTimeout(Task task, TimeSpan timeout)
{
return await Task.WhenAny(Task.Delay(timeout), Task.Delay(timeout)) == task;
}
The problem appears to be in AwaitWithTimeout
, which should complete when either the task or the timeout complete. Instead, it never stops waiting. What I found strange is that, even when I replaced the contents of this method with something like await Task.Delay(timeout)
, it would never finish.
The following shows how I call it from the outer scope:
var foo = channel.GetNextData(TimeSpan.FromSeconds(5));
SendDataRequest();
foo.Wait();
Why does this code never complete?