将事件包装为socket的异步

时间:2015-02-28 11:45:45

标签: c# sockets events asynchronous winrt-async

在C#的WinRT项目中,我使用DatagramSocket发送请求,并通过订阅messagereceived事件等待超时响应。像:

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.

但是我想知道是否可以将所有这些调用包装到单个等待的异步调用中,以便我可以执行类似

的操作
SocketWrapper wrapper;
msg= await wrapper.RequestAndWaitForResponse(TimeSpan.FromSeconds(5));

因此,如果没有响应返回,异步调用将在超时后返回null,如果有响应,异步调用将立即返回消息而不等待超时。

1 个答案:

答案 0 :(得分:2)

将基于事件的API转换为异步调用的最简单解决方案是使用TaskCompletionSource API。

此对象将创建一个等待的任务,直到您调用其中一个SetResult / SetException / SetCanceled方法。

在这种情况下,您可以使用以下代码创建一个在收到MessageReceived事件时完成的任务。

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