【问题标题】:Asynchronous action methods and IO completion ports异步操作方法和 IO 完成端口
【发布时间】:2014-02-20 00:23:51
【问题描述】:

当我们的应用程序依赖外部服务时使用异步编程很重要的原因之一是允许 ASP.NET 使用 IO 完成端口,而不是阻塞等待外部服务响应的线程, ASP.NET 可以将执行停放在一个 IO 完成端口并使用线程来处理另一个请求,每当外部服务响应时,ASP.NET 就会再次获取该执行并恢复它。这样,没有线程被阻塞。

异步方法的一个例子是:

[HttpPost]
public async Task<ActionResult> Open(String key)
{
    Foo foo= await _externalService.GetFoo(key);
    return View(foo);
}

但是如果我们对外部服务使用多个请求会发生什么? ASP.NET 如何处理它?

[HttpPost]
public async Task<ActionResult> Open()
{
    List<Task<Foo>> tasks = new List<Task<Foo>>();

    foreach (var key in this.Request.Form.AllKeys)
        tasks.Add(_externalService.GetFoo(key));

    var foos = await Task.WhenAll(tasks);

    Foo foo = null;
    foreach (var f in foos)
    {
        if (foo == null && f != null)
            foo = f;
        else
            foo.Merge(f);
    }
    return View(foo);
}

它还在使用 IO 完成端口吗?还是因为Task.WhenAll 阻塞了一个线程?

【问题讨论】:

    标签: asp.net multithreading task-parallel-library async-await io-completion-ports


    【解决方案1】:

    它仍然使用 I/O 完成端口。 WhenAll 是异步的,不会阻塞线程。

    【讨论】:

    • 我编辑了这个问题。它不会阻塞“the”线程,但会阻塞任何线程吗?我的意思是,我的理解是 I/O 完成端口允许您在不阻塞线程的情况下停止任务,因为存在关联的 I/O 操作。但在“WhenAll”的情况下,它是如何工作的?
    • WhenAll 只是一个带有计数器的TaskCompletionSource。当您调用它时,它将计数器设置为任务数,并为每个减少计数器的任务附加一个延续。当计数器达到零时,TCS 完成,这允许您的方法继续。没有线程被阻塞。
    猜你喜欢
    • 2018-05-22
    • 2021-08-05
    • 1970-01-01
    • 1970-01-01
    • 2014-02-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多