【问题标题】:Running socket.EndReceive(ar)/BeginReceive in different thread in C#在 C# 的不同线程中运行 socket.EndReceive(ar)/BeginReceive
【发布时间】:2020-04-17 21:07:05
【问题描述】:

我正在 Windows 10 平台上用 C# 编写服务器/客户端套接字应用程序。 服务器端代码和 GUI 代码在同一个进程中运行。在服务器端,我正在尝试优化我的代码,因为我可以拥有 255 个套接字客户端连接。我遵循了微软的“同步服务器套接字示例”。我已经(从他们的例子中)移动了所有的逻辑 “public static void ReadCallback(IAsyncResult ar)”到:

Task.Run(() =>
{
ReadCallback(IAsyncResult ar);
});

.. ,希望“ReadCallback”会被不同的线程调用,因此尽快释放回调套接字线程。 这是否会产生问题,因为我现在调用了可能从不同线程调用的“socket.EndReceive(ar)”和“socket.BeginReceive(...)”? 代码仍然有效,但我不知道这是偶然还是我的设计。请对此发表评论。

【问题讨论】:

  • IAsyncResult 来自 APM,Task.Run 是 TPL,您不应该混合使用这两种方法。 Task.Run 会运行在线程池上,ReadCallback 可能会运行在不同的线程池线程上
  • 不,在添加 Task/async 之前,总是从线程池线程调用 End/BeginReceive()。使用 Task.Run 确实完全违背了使用 BeginReceive() 的目的,即仅在有有用的事情要做时才使用线程并运行代码。混合不是一个好主意。
  • 感谢绅士们的回复。所以一般规则是单独使用 APM 线程池和 live TPL。我理解正确吗?

标签: c# visual-studio sockets


【解决方案1】:

根据 .Net 文档,所有 Socket 调用都是线程安全的。

线程安全

这个类的实例是线程安全的。

我用 Begin.. 和 End.. 在不同的线程中编写了其他代码。然而事后看来,这并不是最好的方法。

我建议每个 TcpClient 连接使用一个任务,处理输入和输出,如果您真的不需要输入和输出之间的同步,那么该任务可以生成一个输入任务和一个输出任务,但仍然在控制 TcpClient 任务。

对于高性能 IO,我建议查看 System.IO.Pipelines

【讨论】:

  • Rowan 我想我会接受上面的建议。感谢您的回答。我一定会看看 Pipelines 包。
猜你喜欢
  • 2022-01-04
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多