加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 编程开发 > asp.Net > 正文

asp.net – 使用“async”(即使它应该完成)作为MVC路由的一部分

发布时间:2020-12-16 00:28:25 所属栏目:asp.Net 来源:网络整理
导读:考虑以下(基于默认的MVC模板),这是在后台发生的一些“东西”的简化版本 – 它完好无损,并显示预期的结果20: public ActionResult Index(){ var task = SlowDouble(10); string result; if (task.Wait(2000)) { result = task.Result.ToString(); } else {
考虑以下(基于默认的MVC模板),这是在后台发生的一些“东西”的简化版本 – 它完好无损,并显示预期的结果20:
public ActionResult Index()
{
    var task = SlowDouble(10);
    string result;
    if (task.Wait(2000))
    {
        result = task.Result.ToString();
    }
    else
    {
        result = "timeout";
    }

    ViewBag.Message = result;
    return View();
}
internal static Task<long> SlowDouble(long val)
{
    TaskCompletionSource<long> result = new TaskCompletionSource<long>();
    ThreadPool.QueueUserWorkItem(delegate
    {
        Thread.Sleep(50);
        result.SetResult(val * 2);
    });
    return result.Task;
}

然而,现在如果我们在混合中添加一些异步:

public static async Task<long> IndirectSlowDouble(long val)
{
    long result = await SlowDouble(val);

    return result;
}

并将路由中的第一行更改为:

var task = IndirectSlowDouble(10);

那么它不行;它代替了。如果我们添加断点,返回结果;在异步方法中只有在路由已经完成之后才会发生,基本上看起来系统不愿意使用任何线程恢复异步操作,直到请求完成。更糟:如果我们使用了.Wait()(或访问.Result),那么它将完全死锁。

那是什么呢?明显的解决方法是“不要异步”,但是在使用库时并不容易。最后,SlowDouble和IndirectSlowDouble之间没有任何功能上的区别(尽管有明显的结构差异)。

注意:在控制台/ winform / etc中完全相同的东西可以正常工作。

解决方法

这与ASP.NET(Pre .NET 4.5)中实现同步上下文的方式有关。关于这个行为有很多问题:

Task.WaitAll hanging with multiple awaitable tasks in ASP.NET

Asp.net SynchronizationContext locks HttpApplication for async continuations?

在ASP.NET 4.5中,本文介绍了同步上下文的一个新实现。

http://blogs.msdn.com/b/webdev/archive/2012/11/19/all-about-httpruntime-targetframework.aspx

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读