长时间运行的阻止方法.阻塞,休眠,开始/结束和异步之间的区别 [英] Long Running Blocking Methods. Difference between Blocking, Sleeping, Begin/End and Async

查看:183
本文介绍了长时间运行的阻止方法.阻塞,休眠,开始/结束和异步之间的区别的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

这个问题与设计或图案以及使用哪个无关.这个问题的核心是关于线程和阻塞的情况.

This question is not about designs or patterns and which to use. The heart of this question is about what is happening regarding threads and blocking.

此示例适用于旨在连续执行相同操作的任何阻止方法.在这种情况下,这是对网络流的阻塞读取或写入.这些方法之间的线程和性能是否在幕后有明显的区别?

This example is to apply to any blocking method that is designed to perform the same action continuously. In this case it is a blocking read or write on a networkstream. Is there any appreciable difference behind the scenes as to threading and performance between the methods?

我的假设是,下面的每个方法都会创建一个线程或使用一个池化线程.然后阻塞该线程,直到有要读取的数据为止.话虽如此,在这种情况下,方法之间的线程,性能和可伸缩性是否有明显的区别?

My assumption is that each of the methods below creates a thread or uses a pooled thread. Then blocks that thread until there is data to be read. Having said that and in that context, Is there any appreciable difference as to threading, performance and scalability between the methods?

当前,我正在创建服务器应用程序.此应用程序将有1000个客户端创建tcp连接.这些连接将保持打开状态,并经常发送和接收少量数据.我希望使用模型A,因为它最容易实现且最易于维护.无论选择哪种模式,我都会得到1000个线程吗?

Currently I am creating a server application. This application will have 1000 clients creating tcp connections. These connections will remain open, sending and receiving small amounts of data often. I am looking to use model A since it is the easiest to implement and the most maintainable. Will I end up with 1000 threads no matter which pattern is chosen?

请注意,这些方法只是为了了解结构,而不是在没有正确的流读取,超时和异常处理的情况下使用的方法.

Please note that these methods are just to give an idea of the structure and not something that would be used without proper streaming reads, timeouts, and exception handling.

方法A:阻止

Task.Factory.StartNew(ReadMessage,TaskCreationOptions.LongRunning);
private void ReadMessage()
{
   while(true)
   {
      TcpClient.Read();
   }
}

方法B:睡觉

Task.Factory.StartNew(ReadMessage,TaskCreationOptions.LongRunning);
private void ReadMessage()
{
    while(true)
    {
        if(TcpClient.DataAvailable)
            TcpClient.Read();
        else
            Thread.Sleep(1);
    }
}

方法C:递归开始/结束

Method C: Recursive Begin/End

private void ReadMessage()
{
      stream.BeginRead(readCallBack)
}
private void readCallBack()
{
      stream.EndRead();
      stream.BeginRead(readCallBack)
}

方法D:从BCL套接字异步.ReceiveAsync()

Method D: Async from BCL socket.ReceiveAsync()

private void readCallBack()
{
    while(true)
    {
        await socket.ReceiveAsync(eventArgs);
    }
}

方法E:阻止读取的异步方法(使用方法D进行调用,但这是一个自定义方法,而不是使用BCL中内置的套接字扩展)

Method E: Async method with blocking Read (Uses method D to call but is a custom method instead of using the built in exstendion of sockets from the BCL)

private async Task<byte[]> ReceiveAsync()
{
   return await Task.Factory.StartNew(() => TcpClient.Read());
}

推荐答案

我的假设是,下面的每个方法都会创建一个线程或使用一个池化线程.然后阻塞该线程,直到有要读取的数据为止.

My assumption is that each of the methods below creates a thread or uses a pooled thread. Then blocks that thread until there is data to be read.

一点也不.前两个示例阻塞了线程,但是后两个示例是异步的.

Not at all. Your first two examples block threads, but your second two examples are asynchronous.

异步方法通过将工作排队到OS,然后等待回调(在这种情况下是在I/O完成端口上)来工作.因此,在等待读取期间,没有任何线程在使用.

Asynchronous methods work by queueing the work to the OS and then waiting for a callback, in this case on an I/O completion port. So while the read is pending, there are no threads being used.

由于异步方法不使用太多线程,因此扩展性更好.

Since asynchronous approaches don't use as many threads, they scale better.

您的最后一个示例(async)实际上和您的第一个示例一样简单,这是我建议的方法,除非您使用Rx或TPL Dataflow.在进行套接字通信时,当您考虑进行错误处理(例如检测到断开的连接)时,异步通信显然是解决之道.

Your last example (async) is really just as simple as your first example, and that would be the approach I recommend unless you use Rx or TPL Dataflow. When doing socket communications, by the time you consider error handling such as detection of dropped connections, asynchronous communication is clearly the way to go.

这篇关于长时间运行的阻止方法.阻塞,休眠,开始/结束和异步之间的区别的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆