1

HttpTaskAsyncHandler 是一个很好的基类,用于在 ASP.NET 4.5 中制作异步 http 处理程序 我想知道运行时如何处理 ProcessRequestAsync 中的多个等待语句。

public class CallbackHandler : HttpTaskAsyncHandler
{
    public override async Task ProcessRequestAsync(HttpContext context)
    {
        int value1 = await Task.Factory.StartNew(() => 1);
        int value2 = await Task.Factory.StartNew(() => 2);
        int value3 = await Task.Factory.StartNew(() => 3);

        context.Response.Write(value1 + value2 + value3);
    }

    public override bool IsReusable
    {
        get { return true; }
    }
}

IIS 线程是否被搁置了 3 次?我最终如何测试/查看这个?将 3 个 await 包装在 async 方法中会更好吗?

编辑: 我担心这段代码需要 IIS-workerthread 4 次来处理这个请求。如果我将它包装在一个异步方法中 - 它会表现得更好吗?

图来自 Jeff Prosise 的 MSDN mag 文章

MSDN 文章

这是解释 ASP.NET 中同步和异步页面处理之间差异的图表。恐怕我的示例会导致从主工作线程(图中的粉红色框)启动 3 个线程,从而增加开销。

IIS -> task1 TP -> IIS -> task2 TP -> IIS -> task3 TP -> IIS

(任务切换到主IIS WT 4次)

或者编译器是否非常聪明,它只是将延续从一个任务传递到下一个任务,并在 3 个任务完成后返回主线程。

IIS -> 任务1 TP -> 任务2 TP -> 任务3 TP -> IIS

(任务切换到主IIS WT 1次)

4

1 回答 1

1

它处理得很好。

在 IIS 中,您为async处理程序提供了一个“请求上下文” async,默认情况下您的方法将在该上下文中恢复。每当您await完成一个不完整的任务时,线程就会返回到线程池(它没有被阻塞),并且当该任务完成时,线程池线程用于async在进入该请求上下文后继续该方法。

因此,没有线程被“保留”,但请求本身是。将多个awaits 放在另一个async方法中不会有什么不同,但是启动多个Tasks 然后等待它们全部完成会有所不同,例如await Task.WhenAll(task1, task2, task3);(假设它们都是独立的,当然)。

我不知道验证这种行为的好方法。

于 2013-05-08T15:53:01.137 回答