C#如何用回调包装事件驱动的代码

C#如何用回调包装事件驱动的代码,c#,multithreading,C#,Multithreading,我使用的是第三方套接字库,尽管这与我的问题有些无关。该库由一个“Socket”类组成,其中包含“ConnectAsync”和“WriteAsync”等方法。控件在调用其中一个方法后立即返回,套接字类在操作完成时引发要通知的事件,例如“ConnectCompleted”和“WriteCompleted”。当收到数据时,该类还会引发一个事件:“PacketArrived” 在我的应用程序中,我想发送数据并等待回复。由于这可能发生在许多地方,所以将上面的套接字类封装在某种帮助器中是有意义的,它可以为我

我使用的是第三方套接字库,尽管这与我的问题有些无关。该库由一个“Socket”类组成,其中包含“ConnectAsync”和“WriteAsync”等方法。控件在调用其中一个方法后立即返回,套接字类在操作完成时引发要通知的事件,例如“ConnectCompleted”和“WriteCompleted”。当收到数据时,该类还会引发一个事件:“PacketArrived”

在我的应用程序中,我想发送数据并等待回复。由于这可能发生在许多地方,所以将上面的套接字类封装在某种帮助器中是有意义的,它可以为我完成所有这些。我还希望它是异步的,这样UI(WPF)在connect/write/wait for reply期间不会冻结,因此helper方法调用可能类似于以下内容:-

SocketHelper.SendData(dataToSend, myCallback);
其中,当接收到数据时调用“myCallback”


由于不熟悉线程,我不知道如何编写这个帮助程序——不知何故,它需要将各种方法和事件串在一起,即打开连接,等待连接完成,写入数据,等待写入完成,然后等待数据包到达(然后调用提供的回调)。感谢您的帮助。

Stephen Toub在“”中讨论了.NET 4.5的此主题。只需做一点工作,就可以对.NET4使用相同的技术

您可以使用任务并行库而不是使用回调来执行。使用TPL,您可以将所有套接字操作和回调转换为调用这些操作并处理结果的任务

使用ContinueWith等方法可以非常轻松地组合任务,只有在第一个任务完成时,才能执行链中的下一个任务

任务是使用线程池中的线程执行的,因此您不必担心线程问题

TPL已经提供了一种从成对的BeginXXX/EndXXX函数或IAsyncResult对象创建任务的方法。如果套接字库提供了这些功能,则可以立即开始使用任务

要处理事件,可以使用Task Parallel库中的TaskCompletionSource创建一个任务,该任务将在调用套接字方法时启动,并仅在引发相应事件时完成。“”中描述了该技术

库使用此技术为提供异步方法版本

使用“任务和EAP”中的代码,您可以为套接字类编写如下扩展方法:

public static Task ConnectTask( this Socket socket, object address) 
{ 
    var tcs = CreateSource(address); 
    socket.ConnectCompleted += 
        (sender, e) => TransferCompletion(tcs, e, () => e.Result, null); 
    socket.ConnectAsync(address, tcs); 
    return tcs.Task; 
}
var connectTask=mySocket.ConnectTask(myaddress);
connectTask.ContinueWith(t=> { ... });
然后像这样使用它:

public static Task ConnectTask( this Socket socket, object address) 
{ 
    var tcs = CreateSource(address); 
    socket.ConnectCompleted += 
        (sender, e) => TransferCompletion(tcs, e, () => e.Result, null); 
    socket.ConnectAsync(address, tcs); 
    return tcs.Task; 
}
var connectTask=mySocket.ConnectTask(myaddress);
connectTask.ContinueWith(t=> { ... });

在.NET4.5中,事情变得更加简单。async/await关键字允许您删除ContinueWith调用,并编写与同步版本非常相似的代码。您可以在“”中查找专门用于套接字的扩展。

首先阅读c#事件和委托的入门知识。我认为包装库可能是一个过渡性的桥梁,您不需要使用.NET事件机制传递回调。哪个框架版本。NET4有任务并行库来帮助处理这些问题issues@PanagiotisKanavos它是.Net4@JeffWatkins我的应用程序中有多个地方可以发送数据,所以我不想每次都要处理大量的套接字事件。将connect-send-receive功能封装在一个方法中似乎是一种干净的方法,通过回调表示它已接收到数据,从而在方法执行时保持UI的响应。TaskCompletionSource听起来很完美。套接字库仅公开事件(没有Begin/EndXxxx方法)。非常感谢。@panagiotis Kanavos请更新您的链接,它们都不起作用