BeginFlush 似乎同步工作

BeginFlush seems to work synchronously

我正在尝试使用 HttpResponse BeginFlush 和 EndFlush 方法来使刷新异步,这意味着在刷新到流时不会使用我的工作线程。

但是似乎 BeginFlush 方法 运行 总是以同步方式进行。 我深入研究了 Microsoft 参考代码,但没有找到此行为的原因。 这是微软的实现:http://referencesource.microsoft.com/#System.Web/HttpResponse.cs,f121c649c992c407

我检查了 SupportsAsyncFlush 标志,结果为真,所以我的环境实际上支持 AsyncFlush。

有什么想法吗?

这是一个尝试执行异步刷新的代码片段,但我没有进入 "Different Threads" 行 - 它始终与 运行 这段代码相同的线程。

        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);

代码是异步,但不是多线程。您正在定义回调;一种方法,当冲洗完成时,将来某个不确定的点将是 运行。这并不一定意味着它将 运行 在另一个线程上。

.NET 中也有许多抽象功能的实现,其中行为被定义为异步,但实现是同步的,因为该特定实现期望 运行 如此之快以至于不保证异步。对于相当一部分 .NET 的文件 IO 来说是这样。如果您使用的编写器希望能够非常快速地刷新缓冲区,那么它可能不会费心异步执行此操作。

您看到的效果可能与ASP.NET使用的SycnhronizationContext有关。根据 .NET 版本以及您的代码是否在 ASP.NET 页面或其他页面下执行,行为可能会发生变化。通常,SynchronizationContext 在启动异步操作的同一线程上执行回调是正常的。您可以在此处找到更多信息:https://msdn.microsoft.com/en-us/magazine/gg598924.aspx

在任何情况下,您都可以通过检查下一行代码(在 BeginFlush 之后)在回调之前执行的情况来检查回调是否同步。那将表明回调确实是异步的。