异步委托与线程
用异步代理(回调)替换线程(而不是ThreadPool线程)。
我的场景:为每个客户端生成一个Thread / del.beginInvoke()。
据我说,
原因
- 在Callback中需要再次通过Callback / Call delegate进行通知
- 避免线程开销,(委托使用Threadpool线程)
- 传递参数(避免转换为对象)并需要从方法返回值。
如果上述原因错误,请纠正我。
- 还有其他原因吗?
- 什么情况我确实需要用线程不能的异步委托做一些事情?
3.表现?
例
public delegate void SendCallbackType(); SendCallbackType senderdel= new SendCallbackType(SendData); public void StartSend() // This method Could be Called more than 700 times (Thread per Client) { senderdel.BeginInvoke(SendCallback,null); // (or) Thread t = new Thread(new ThreadStart(ThreadSend)); t.IsBackground = true; t.Start(); } //Async Delegate void SendData() { string data = QueData.DeQueue(); RaiseOnData(data); // Raise to event. } void SendCallback(IAsyncResult ar) { senderdel.BeginInvoke(SendCallback, null); } //Thread void ThreadSend() { while (true) { string data = QueData.DeQueue(); RaiseOnData(data); // Raise to event. } }
从上面哪个选项将是最好的。 表现?
你的推理是正确的。 异步委托使用线程池中的线程,因此与手动创建线程相比,它们应该更快。 但是在ASP.NET应用程序中要小心。 因为您将占用通常由ASP.NET用于服务请求的工作线程,并且您的应用程序可能很快耗尽服务function。
异步委托适用于CPU密集型任务。 对于I / O密集型任务(例如读取流,数据库调用和Web服务调用),您应该使用由相应类(Stream,SqlConnection,WebClient,…)直接提供的BeginXXX,EndXXX方法。 这样,在冗长的I / O操作期间,您根本不使用任何线程。 您正在使用I / O完成端口 ,这是I / O绑定任务方面的最佳选择。 与任何线程和线程池相比,它将具有更高性能和更低的性能。
总结一下:
- 对于I / O密集型任务,请使用I / O完成端口。 如果I / O密集型任务被包装在一个写得不好的库中,而这个库没有提供这种可能性,请使用.NET 4.0中引入的TPL。
- 对于CPU密集型任务,请使用.NET 4.0中引入的TPL。
如果您没有.NET 4.0使用线程池,除非您正在编写ASP.NET应用程序,在这种情况下您可能需要手动创建线程。
一般来说,最好开始使用TPL并将方法定位为任务,以便为.NET 4.5做好准备,它引入了async / await关键字。