malfoyjohn
malfoyjohn

Reputation: 21

Wrap event to async for socket

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

Answers (1)

Vincent
Vincent

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

Related Questions