我读到的关于.NET中套接字的所有内容都说异步模式提供了更好的性能(特别是使用新的SocketAsyncEventArgs可以节省分配)。
我认为如果我们谈论的是具有许多客户端连接的服务器,而不能为每个连接分配一个线程,那么这是有意义的。然后我可以看到使用ThreadPool线程并在它们上获得异步回调的优势。
但在我的应用程序中,我是客户端,我只需要通过一个tcp连接收听一个服务器发送市场价格数据。现在,我创建一个单独的线程,将优先级设置为Highest,并使用它调用Socket.Receive()。我的线程阻止此调用,并在新数据到达时唤醒。
如果我要将其切换为异步模式,以便在有新数据时收到回调,我会看到两个问题
线程池线程将具有默认优先级,因此看起来它们将严格地比我自己的具有最高优先级的线程更差。
我仍然需要在某个时刻通过单个线程发送所有内容。假设我几乎同时在N个不同的线程池线程上得到N个回调,通知我有新数据。它们提供的N字节数组无法在线程池线程上处理,因为无法保证它们代表N个唯一的市场数据消息,因为TCP是基于流的。我将不得不锁定并将字节放入数组中,并发出一些其他线程的信号,这些线程可以处理数组中的内容。所以我不确定N线程池线程是买什么的。
我在想这个错吗?是否有理由在我的特定情况下使用异步模式连接到一个服务器?
更新:
所以我认为我误解了上面(2)中的异步模式。当有数据可用时,我会在一个工作线程上得到回调。然后我会开始另一个异步接收并获得另一个回调等。我不会同时得到N个回调。
问题仍然是一样的。有什么理由说回调在我的客户端并且只连接到一台服务器的特定情况下会更好。
答案 0 :(得分:5)
您应用程序中最慢的部分是网络通信。通过调整这样的事情,你很可能对一个线程,一个连接客户端的性能几乎没有影响。网络通信本身将使处理或上下文切换时间的所有其他贡献相形见绌。
说我几乎得到了N个回调 同时在N不同 线程池线程通知我 有新数据。
为什么会发生这种情况?如果你有一个套接字,你可以Begin
对它进行操作来接收数据,并在完成后得到一个回调。然后,您决定是否进行其他操作。这听起来像是你过于复杂,但也许我对你想要做的事情过于简单化了。
总而言之,我会说:选择最简单的编程模型,让你得到你想要的东西;考虑到您的场景中可用的选择,无论您选择哪一个,他们都不太可能对性能产生任何明显的差异。使用阻塞模型,你“浪费”一个可以做一些真正工作的线程,但是嘿......也许你没有任何真正的工作要做。
答案 1 :(得分:3)
性能的第一条规则只是在必要时尝试改进它。
我看到你提到标准,但从未提及问题,如果你没有,那么你不必担心标准所说的。
答案 2 :(得分:2)
"This class was specifically designed for network server applications that require high performance.“
据我了解,此处您是客户端,只有单连接。
此连接上的数据按顺序到达,由单个线程使用。
如果您改为在不同的线程上接收少量数据,那么您可能会失去性能,只是为了以后可以在序列化中组装它们 - 因此就像单线程一样。 关于什么都没有。
你真的不需要加快速度,你可能不会。
你不需要SocketAsyncEventArgs。 可能会加快速度。
一如既往,衡量&衡量。
另外,仅仅因为你可以,这并不意味着你应该这样做
如果在可预见的未来表现足够,那么为何复杂化呢?