我还没有完全“得到”异步和等待,我正在寻找一些关于我将要解决的特定问题的澄清。基本上,我需要编写一些代码来处理TCP连接。实际上,它只需要接收数据并处理它,直到连接关闭。
我通常使用NetworkStream BeginRead和EndRead模式编写这段代码,但是由于异步/等待模式要干净得多,所以我很想使用它。然而,由于我承认我并不完全理解其中所涉及的问题,所以我对其后果有点警惕。其中一个会比另一个使用更多的资源;其中一个会使用线程,而另一个会使用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)‘循环将使用额外的线程、更多的资源,因此不会像另一个线程那样扩展。但我敢肯定这是错的。他们用同样的方式做同样的事情吗?
发布于 2014-10-30 11:59:19
在我看来,异步方式看起来更干净,但我的未受过教育的大脑告诉我,'while (true)‘循环将使用额外的线程、更多的资源,因此不会像另一个线程那样扩展。
不,它不会。循环只在它实际运行代码时使用线程.就像在您的BeginRead回调中一样。await表达式将返回对任何调用代码的控制,它注册了一个继续,它跳回方法中的正确位置(在适当的线程中,基于同步上下文),然后继续运行,直到它到达方法的末尾或碰到另一个await表达式。这正是你想要的:)
更多关于异步/等待如何在幕后工作的信息值得学习--您可能想从the MSDN page on it开始,作为起点。
https://stackoverflow.com/questions/26652328
复制相似问题