异步委托与线程的区别

7

使用异步委托(回调)替换线程(而不是线程池线程)。

我的情况:针对每个客户端生成一个线程/del.beginInvoke()。

根据我的理解:

原因:

  1. 需要通过回调进行通知/在回调中再次调用委托
  2. 避免线程开销,(委托使用线程池线程)
  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.
      }
   }

从上述内容来看,哪个选项最好?性能?
1个回答

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,该版本引入了异步/等待关键字。


@ Darin:感谢您的回复。这里是Windows应用程序,我认为这是纯CPU密集型任务,那么在生成1000个线程与调用1000个del.begininvoke()时的性能如何? - C-va
@MSK,在这种情况下,一定要选择TPL。如果您正在使用较旧版本的.NET,请使用线程池(ThreadPool、BackgroundWorker、Async委托等),它们最终都会在线程池中结束。不要手动创建线程。 - Darin Dimitrov
@ Darin:我不需要“Fire and forget”。在这里,我需要一个专用线程来出队(无论线程池如何),同时它是长时间运行的进程。 - C-va
你是在谈论生产者/消费者模式吗? - Darin Dimitrov
当然可以(它应用于队列的出队操作) - C-va
显示剩余4条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接