我尝试使用HttpResponse BeginFlush和EndFlush方法来刷新异步,这意味着我的工作线程在刷新到流时不会被使用。
然而,似乎BeginFlush方法始终以同步方式运行。 我深入研究了Microsoft参考代码,并没有找到这种行为的原因。 这是Microsoft实施:http://referencesource.microsoft.com/#System.Web/HttpResponse.cs,f121c649c992c407
我查看了SupportsAsyncFlush标志,并且我得到了真的,所以我的环境实际上支持AsyncFlush。
有什么想法吗?
这是尝试执行异步刷新的代码段,但我没有进入"不同的线程" line - 它始终是运行此代码的相同线程。
Context.Response.Write("Some message");
Context.Response.BeginFlush(
res =>
{
try
{
var previousThreadId = (int)res.AsyncState;
var thread2Id = Thread.CurrentThread.ManagedThreadId;
if (previousThreadId != thread2Id)
{
Console.WriteLine("Different Threads");
}
Context.Response.EndFlush(res);
}
catch (Exception e)
{
}
},
Thread.CurrentThread.ManagedThreadId);
答案 0 :(得分:3)
代码是异步,但它不是多线程。您正在定义回调;当冲洗完成时,将在未来的某个不确定点运行的方法。这并不一定意味着它将在另一个线程上运行。
在.NET中还有许多抽象功能的实现,其中行为被定义为异步,但实现是同步的,因为特定的实现期望运行得如此之快以至于不能保证异步。这对于.NET的文件IO来说确实如此。如果您正在使用的编写器希望能够非常快速地刷新缓冲区,则可能不会异步地执行此操作。
答案 1 :(得分:2)
您看到的效果可能与ASP.NET使用的SycnhronizationContext有关。根据.NET版本以及您的代码是在ASP.NET页面或其他内容下执行,行为可能会发生变化。通常,SynchronizationContext在启动异步操作的同一线程上执行回调是正常的。您可以在此处找到更多信息:https://msdn.microsoft.com/en-us/magazine/gg598924.aspx
在任何情况下,您都可以通过在回调之前检查代码的下一行(在BeginFlush之后)执行weather来检查回调是否是同步的。这表明回调确实是异步的。