异步委托与线程

C-v*_*-va 7 c# delegates asynchronous

用异步委托(回调)替换线程(而不是ThreadPool线程).

我的场景:为每个客户端生成一个Thread/del.beginInvoke().

据我说,

原因

  1. 需要在Callback中通过Callback/Call delegate再次通知
  2. 避免线程开销,(委托使用Threadpool线程)
  3. 传递参数(避免转换为对象)并需要从方法返回值.

如果上述原因错误,请纠正我.

  1. 还有其他原因吗?
  2. 什么情况我确实需要用线程不能的异步委托做一些事情?
    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.
      }
   }
Run Code Online (Sandbox Code Playgroud)

从上面哪个选项将是最好的.表现?

Dar*_*rov 10

你的推理是正确的.异步委托使用线程池中的线程,因此与手动创建线程相比,它们应该更快.但是在ASP.NET应用程序中要小心这一点.因为您将占用通常由ASP.NET用于服务请求的工作线程,并且您的应用程序可能很快耗尽服务功能.

异步委托适用于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关键字.