确定网络客户端连接时如何正确排队工作
本文关键字:何正确 排队 工作 连接 网络 客户端 | 更新日期: 2023-09-27 17:53:39
我一直在读关于Threadpool.QueueUserWorkItem
(我一直在使用的内容(、Task.Run
和Task.Factory.StartNew
的文章,但我仍然不清楚这里的正确选项是什么。似乎由于我的工作不受CPU限制,我可能不应该使用Task.Run
我有自己的线程在运行,等待连接:
Thread listenThread = new Thread(() => ListenForConnection());
listenThread.Name = "lThread";
listenThread.IsBackground = true;
listenThread.Start();
我只是在做:
tlist = new TcpListener(IPAddress.Parse(ip.ToString()), 27275);
tlist.Start();
while (isRunning) {
try {
var client = await tlist.AcceptTcpClientAsync();
ThreadPool.QueueUserWorkItem(HandleClient, client);
}
catch (Exception) { }
}
HandleClient
解析客户端发送的消息,创建一个简单类的实例,或者在客户端已经存在的情况下更新现有的实例,存储对连接的引用,还更新一些UI元素。
ThreadPool.QueueUserWorkItem
是这里的首选方法吗?还是我太差了?
编辑:需要注意的是,HandleClient
函数通常需要5到30毫秒,因此的工作量不是很大
QueueUserWorkItem
、StartNew
和Run
或多或少是等效的。我选择Task.Run
是因为它是最现代的方式
你的方法完全可以。你选择了一个同步HandleClient
实现,它迫使你在一个单独的线程上处理连接。请注意,在许多并发连接的情况下,这可能会消耗许多资源。如果你对这种情况不感兴趣,这不是问题。否则,它就是一个交易破坏者。
如果您使HandleClient
真正异步且无阻塞,则不需要将该调用推送到线程池中。我的建议是仍然这样做,因为它几乎没有缺点,而且它可以保护您免受该方法中过长的同步初始部分的影响。
catch (Exception) { }
我不明白。这可能会隐藏错误。此外,如果有一个错误,很可能是一个永久性错误。这种错误处理将把循环变成一个占用100%CPU代码的繁忙循环。将锁扣移到环外。
我会这样说:
var tcpListener = new TcpListener(IPAddress.Any, 80);
tcpListener.Start();
while (true)
{
var tcpClient = tcpListener.AcceptTcpClient();
Task.Factory.StartNew(() =>
{
// Do whatever you like with your TcpClient
});
}