I am confused as to how best handle this situation. I wan't to await the response of an asynchronous call. Specifically I have:
public async Task<IApiData> FetchQueuedApiAsync(TimeSpan receiveTimeout)
{
var message = await Task.Factory.FromAsync<Message>(
ReadQueue.BeginReceive(receiveTimeout), ReadQueue.EndReceive);
return message.Body as IApiData;
}
This works as expected. However, if the timeout expires then ReadQueue.EndReceive must not be called else it will throw an exception. Obviously FromAsync doesn't know this and calls it blindly - firing the exception. The requirement not to call EndReceive on timeouts is implemented by MSMQ and beyond my control.
The queue exposes an event when a message is ready or a timeout occurs. This is where you would normally check if a message was present, and THEN call EndReceive as per the documentation. Standard listener....
ReadQueue.ReceiveCompleted += ReadQueue_ReceiveCompleted;
My question is that I don't understand how to do that and still have this as awaitable (i.e. I want to be able to await like I have now, but handle it via the delegate). Does that make sense?
As a rule when you want to convert some non-task based asynchronous model to a task based asynchronous model, if there isn't already a
Task
method to do the conversion for you, you use aTaskCompletionSource
to handle each of the cases "manually":You'll need to adjust this based on the specifics of the types you didn't show, but this is the general idea.