BeginFlush似乎同步工作

时间:2015-01-21 15:24:31

标签: c# .net multithreading .net-4.5 httpresponse

我尝试使用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);

2 个答案:

答案 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来检查回调是否是同步的。这表明回调确实是异步的。