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

时间:2011-04-28 06:36:37

标签: c# multithreading sockets tcp client-server

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

我的直觉告诉我阻止这种方法是合理的,但是看一下really nice example of sockets in C#我发现他们正在创建一个新线程。我在创建另一个线程时遇到的主要问题是错误处理。

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

2 个答案:

答案 0 :(得分:4)

如果您在UI线程上调用SendMessage(),那么它将阻止它,您的应用程序将“冻结”。不是每次要发送数据时都创建新线程,而是使用.NET 4.0中的Task Parallel Library中的ThreadPool.QueueUserItem(o => SendMessage())Task.Factory.StartNew(() => SendMessage())

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

为每个客户端创建一个新线程有一个缺点:许多线程会消耗大量资源,并且大多数时候这些线程将在空闲时同时为其他客户端提供服务。如果您希望创建一个高性能服务器应用程序,您应该了解异步编程。

结帐Async CTP。它将允许您编写看起来像同步代码的异步代码,而不会出现混乱的回调

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

现在SendMessage()不会阻塞,因为它将以异步方式执行,它看起来并不可怕!

答案 1 :(得分:0)

我强烈建议您查看Task Parallel Library

您可以从当前.net中的任何异步模式创建任务。

任务将在线程池上执行,异常将从其他线程中进行封送。