Reputation: 21
In a WinRT project in C#, I used a DatagramSocket to send a request and wait with timeout for a response by subscribe to the messagereceived event. Like:
DatagramSocket socket=new DatagramSocket();
socket.MessageReceived+=(sender,args)=>{
if(!timeout){
... do stuff to handle the msg
}else{ ..discard the msg..}
}
...
//later I do something like socket.send() to send out the request and start the timer.
However I wonder if it's possible to to wrap all those calls in to a single awaitable async call so that I can do something like
SocketWrapper wrapper;
msg= await wrapper.RequestAndWaitForResponse(TimeSpan.FromSeconds(5));
So if no response come back, the async call will return a null after the timeout, and if there's a response, the async call will return right away with the message without waiting for the timeout.
Upvotes: 2
Views: 968
Reputation: 3746
The most simple solution to convert event based API to async calls is to use the TaskCompletionSource API.
This object will create a task that will be awaited until you call one of the SetResult/SetException/SetCanceled methods.
In you case, you can create a task that will complete when the MessageReceived event is received using the following code.
public Task<T> CreateMessageReceivedTask()
{
var taskCompletionSource = new TaskCompletionSource<T>();
var socket=new DatagramSocket();
socket.MessageReceived += (sender,args) =>
{
if(!timeout)
{
// ... do stuff to handle the msg
taskCompletionSource.SetResult(<your result>);
}
else
{
//..discard the msg..
taskCompletionSource.SetException(new Exception("Failed"));
}
});
}
Upvotes: 3