- c - 在位数组中找到第一个零
- linux - Unix 显示有关匹配两种模式之一的文件的信息
- 正则表达式替换多个文件
- linux - 隐藏来自 xtrace 的命令
我还不太“了解”async 和 await,我正在寻找关于我将要解决的特定问题的一些说明。基本上,我需要编写一些代码来处理 TCP 连接。它基本上只是接收数据并处理它,直到连接关闭。
我通常使用 NetworkStream BeginRead 和 EndRead 模式编写此代码,但由于 async/await 模式更简洁,我很想改用它。然而,由于我承认并不完全理解其中涉及的确切内容,所以我对后果有点担心。一个人会比另一个人使用更多的资源吗?一个人会使用一个线程,而另一个人会使用 IOCP 等。
复杂的示例时间。这两个做同样的事情 - 计算流中的字节数:
class StreamCount
{
private Stream str;
private int total = 0;
private byte[] buffer = new byte[1000];
public Task<int> CountBytes(Stream str)
{
this.str = str;
var tcs = new TaskCompletionSource<int>();
Action onComplete = () => tcs.SetResult(total);
str.BeginRead(this.buffer, 0, 1000, this.BeginReadCallback, onComplete);
return tcs.Task;
}
private void BeginReadCallback(IAsyncResult ar)
{
var bytesRead = str.EndRead(ar);
if (bytesRead == 0)
{
((Action)ar.AsyncState)();
}
else
{
total += bytesRead;
str.BeginRead(this.buffer, 0, 1000, this.BeginReadCallback, ar.AsyncState);
}
}
}
……还有……
public static async Task<int> CountBytes(Stream str)
{
var buffer = new byte[1000];
var total = 0;
while (true)
{
int bytesRead = await str.ReadAsync(buffer, 0, 1000);
if (bytesRead == 0)
{
break;
}
total += bytesRead;
}
return total;
}
在我看来,异步方式看起来更简洁,但是我未受过教育的大脑告诉我的“while (true)”循环将使用额外的线程、更多资源,因此不会像以前那样扩展另一个。但我相当确定那是错误的。这些是否以相同的方式做相同的事情?
最佳答案
To my eyes, the async way looks cleaner, but there is that 'while (true)' loop that my uneducated brain tells me is going to use an extra thread, more resources, and therefore won't scale as well as the other one.
不,不会的。循环将仅在实际运行代码时使用线程...就像在您的BeginRead
回调中一样。 await
表达式将控制权返回给任何调用代码,注册了一个延续,它跳回到方法中的正确位置(在适当的线程中,基于同步上下文),然后继续运行直到它到达方法的末尾或遇到另一个 await
表达式。这正是您想要的:)
值得了解更多有关 async/await 在幕后如何工作的信息 - 您可能想从 the MSDN page on it 开始, 作为一个起点。
关于c# - 异步/等待 vs BeginRead、EndRead,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26652328/
这个小项目背后的想法是开发一个不同的聊天应用程序,我想发送对象而不是纯字符串。到目前为止,这就是我所拥有的。 如果我在构造函数上反序列化,它工作得很好(UserDTO 目前只有 2 个字符串字段),但
我正在尝试写一个 TcpClient执行。我想在处理数据时开始下一次读取,但我不确定何时将字节数组传递给 BeginRead被修改。这是我当前的实现 private void ProcessData(
我无法找到在成功的 HttpWebRequest 后取消/终止异步读取操作的方法。无法设置超时,ThreadPool.RegisterWaitForSingleObject 也不起作用。并且关闭底层套
关于这篇文章: http://msdn.microsoft.com/en-us/library/system.net.security.sslstream.beginread.aspx 是否有关于如何
我需要从我的虚拟 com 端口读取数据并检测消息“Dreq”。一旦我按下连接按钮,它就会连接到我的 COM8 端口并开始读取新线程。我还有一个断开连接按钮,我希望在其中关闭读数并断开与 COM8 端口
我正在用 TcpClient 编码一个服务器/客户端项目和 NetworkStream对象。我希望许多客户端连接到服务器,这些客户端存储在 List<> 中定制NetworkNode对象,每个对象都有
我正在编写一个类,该类公开流的一部分以供阅读。由于可能同时从多个不同的子部分读取数据,因此在任何时候只能进行一个操作。 我想到了在每次操作之前锁定底层流。在 BeginRead 调用周围锁定流是否足以
我正在运行一个有 5000 个 UdpClient 实例的应用程序类,因为我需要在不同的端口上同时传输数据包。 我目前正在使用 System.Timers.Timer ,它在 ThreadPool 上
有一个异步服务器的代码。 Client 发送 Header - Data Block + Data Block 的大小。 服务器首先异步读取Header,然后读取Data Block。 我需要在读取数
好的,我想连接到 Socket 并使用 System.Net.Sockets.NetworkStream 类读取网络流。这是我目前所拥有的: NetworkStream myNetworkStream
使用 .NET TcpClient 如果我在关联的网络流上调用了异步 BeginRead(),我仍然可以调用 Write()在另一个线程的那个流上? 或者我是否必须 lock() 从 BeginRea
假设我有一个流链,执行压缩 -> 加密 -> 文件 I/O。 在 C# 中,使用同步 I/O,它看起来像这样: int n=0; byte[] buffer= new byte[2048];
运行这段代码时: private async void StartChat(Object obj) { TcpClient me = (TcpClient)obj; UpdateCha
当使用异步代码通过 BeginXXX/EndXXX 模式从流等中读取时,我相信在调用 EndXXX 时会抛出在此过程中发生的任何异常。 这是否意味着对 BeginXXX 的初始调用永远不会抛出异常,它
我有一个用 C# 编写的实用程序,用于与我们的 USB 设备来回通信。我们使用通用 HID 驱动程序并将设备句柄包装在 FileStream 对象中。我使用它的 BeginRead 和 BeginWr
我还不太“了解”async 和 await,我正在寻找关于我将要解决的特定问题的一些说明。基本上,我需要编写一些代码来处理 TCP 连接。它基本上只是接收数据并处理它,直到连接关闭。 我通常使用 Ne
它在 MSDN documentation 中声明那: at the very minimum, your state parameter must contain the connected or
为什么使用 FileOptions.Asynchronous 创建 FileStream 会导致 FileStream.BeginRead 阻塞调用线程? 这是代码片段: private static
我创建了 ReadByteContainer 来存储当前数据,并创建了 ReadByteAsyncCallback 用于回调。是否有更好的替代方案? HRESULT MediaByte
我实现了一个模拟串行端口的 DataReceived 事件的系统,通过使用 BeginRead() 方法触发从 TCPClient 对象的 NetworkStream 读取数据,如下所示: TcpCl
我是一名优秀的程序员,十分优秀!