在多线程环境中使用 .Net UdpClient
Posted
技术标签:
【中文标题】在多线程环境中使用 .Net UdpClient【英文标题】:use .Net UdpClient in a multithreaded environment 【发布时间】:2013-01-29 21:45:36 【问题描述】:我有一个服务于一些线程的类的实例(我们称之为 A),这个实例只通过 UdpClient 类发送 UDP 数据包。 它在其构造函数中初始化 UdpClient,仅用于发送数据包。
它看起来像:
public class A
private UdpClient m_Client;
public class A(string host, int port)
m_Client = new UdpClient(host, port);
public void Send(string dataToSend)
var data= encoding.GetBytes(dataToSend);
client.BeginSend(data, data.Length, null, null);
我的问题是:
我知道 UdpClient 不是线程安全的(根据 MSDN 文档),在不使用锁定机制的情况下支持多线程的最佳方法是什么?
在每次发送时创建 UdpClient 的新实例? (只需使用一些本地 UdpClient 变量)。 性能?
为 UdpClient 使用 ThreadLocal?但是在这种情况下如何处理 UdpClient 呢?
还有其他解决方案吗?
【问题讨论】:
但是您不喜欢将锁定机制用于非线程安全的类? 出于性能考虑,我不想使用锁定机制... 锁定机制是解决此问题的最佳方法。您也可以自己编写锁定机制,但我认为它不会比微软提供的更快。您还写道,您可以为每个线程启动本地 UdpClient,它会起作用。但这不是正确的方法,您将通过锁定机制获得更多性能。启动新的 Udp 客户端需要太多时间,因此您应该尽量减少 UdpClient 启动的次数。实际上,我也有兴趣听取其他用户对这个问题的意见。 我没有看到 1) 有任何明显的性能问题。如果您按时处理它们,就不会有任何问题。 有趣的是,找不到UdpClient初始化的性能信息。如果它确实没有花费任何东西,那么 1) 是最好的解决方案,我相信。但我不确定性能... 【参考方案1】:最终我相信我当前的实现应该没有问题(只要 Microsoft 不会更改 UdpClient 类的实现)。
可能对谁感兴趣: http://social.msdn.microsoft.com/Forums/en-US/csharpgeneral/thread/cbdd9818-00f0-499f-a935-d8e555899d64
【讨论】:
【参考方案2】:我认为这里最好的方法是在每次调用该方法时创建一个新的UdpClient
。这样,您可以确保代码是安全的。性能不太可能是问题,如果性能分析显示问题是,那么您应该开始解决该问题。
此外,您不应忘记在每个 BeginSend()
之后调用 EndSend()
(最好在回调中)。
【讨论】:
使用此特定代码示例的这种方法我看到的警告是,每次调用Send()
时,它都可能“从下面拉出地毯”一个已经在进行中的操作。这是因为客户端存储在类级别变量m_Client
中。作者需要确保创建客户端并将其存储在Send()
中的局部变量中,最好包裹在using
语句中。这可能会确保这个答案中的方法是安全的。以上是关于在多线程环境中使用 .Net UdpClient的主要内容,如果未能解决你的问题,请参考以下文章
可以在多线程环境中使用单个 QueueConnection 吗?