是否应该异步执行对 NetworkStream 的写入

Max*_*ich 1 c# sockets multithreading tcp client-server

考虑到这NetworkStream.Write()是一个阻塞调用,是否应该SendMessage()创建一个新线程之类的方法来执行写入操作,或者该SendMessage()方法应该阻塞直到发送消息或发生异常?

我的直觉告诉我,阻止这个方法是合理的,但是查看C# 中一个非常好的套接字示例,我发现它们正在创建一个新线程。我发现创建另一个线程的主要问题是错误处理。

PS:我知道 Write、Read 等的异步版本,但发现 IAsyncResult 相当混乱,目前暂缓使用这些选项。

mak*_*mak 7

如果您正在调用SendMessage()UI 线程,那么它将阻止该线程,并且您的应用程序将“冻结”。不必每次要发送数据时都创建一个新线程,而是使用.NET 4.0 中的任务并行库中的ThreadPool.QueueUserItem(o => SendMessage())Task.Factory.StartNew(() => SendMessage())

如果您的应用程序正在为客户端提供服务,并且您为每个客户端创建一个新线程,那么SendMessage()如果您不想在将数据发送到客户端时执行其他工作,则可以阻塞。

为每个客户端创建一个新线程有一个缺点:大量线程将消耗大量资源,并且大多数时候这些线程将处于空闲状态,同时它们可以为其他客户端提供服务。如果您希望创建高性能服务器应用程序,您应该学习异步编程。

查看异步 CTP。它可以让你编写看起来像同步代码的异步代码,而没有混乱的回调

public async void SendMessage()
{
    try {
        await socket.WriteAsync(buffer, 0, buffer.Length);
    } catch (...) {
        // handle it
   }
}
Run Code Online (Sandbox Code Playgroud)

现在 SendMessage() 不会阻塞,因为它将异步执行,而且看起来一点也不可怕!