gpt4 book ai didi

c# - 异步/等待 vs BeginRead、EndRead

转载 作者:太空狗 更新时间:2023-10-29 21:22:16 27 4
gpt4 key购买 nike

我还不太“了解”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/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com