【问题标题】:Calling method from MVC controller hangs due to async await由于异步等待,来自 MVC 控制器的调用方法挂起
【发布时间】:2015-10-05 21:07:36
【问题描述】:

我一直在尝试创建一个基于 https://github.com/JeffGos/urbanairsharp 的 REST 包装器。

public LoginResponse Login()
    {
        return SendRequest(new LoginRequest(new Model.Login()));
    }

private static TResponse SendRequest<TResponse>(BaseRequest<TResponse> request) where TResponse : BaseResponse, new()
    {
        try
        {
            var requestTask = request.ExecuteAsync();

            return requestTask.Result;
        }
        catch (Exception e)
        {
            //Log.Error(request.GetType().FullName, e);

            return new TResponse()
            {
                Error = e.InnerException != null ? e.InnerException.Message : e.Message,
                Ok = false
            };
        }
    }

我完全可以从控制台应用程序调用 Login 方法,但如果我从 MVC 控制器调用它,它会很好地逐步执行代码,但永远不会超过该行

var requestTask = request.ExecuteAsync();

我已经阅读了该主题,但不太了解如何从 Web 应用程序中使用这些方法? Login() 方法不是异步的,所以我不明白为什么它会因我的 MVC 操作而失败(也是非异步的)?

谢谢

【问题讨论】:

  • 我相信this 可能会得到你的答案。

标签: c# asp.net-mvc async-await


【解决方案1】:

这个:

var requestTask = request.ExecuteAsync();
return requestTask.Result;

导致您的代码死锁。您正在阻止异步方法与对Task.Result 的调用同步,这就是you shouldn't block on async code 的原因。相反,您需要使用 await 异步等待 ir。这将有效地使您的调用链也变得异步:

public Task<LoginResponse> LoginAsync()
{
    return SendRequestAsync(new LoginRequest(new Model.Login()));
}

private static async Task<TResponse> SendRequestAsync<TResponse>(BaseRequest<TResponse> request) where TResponse : BaseResponse, new()
{
    try
    {
        return await request.ExecuteAsync();
    }
    catch (Exception e)
    {
        //Log.Error(request.GetType().FullName, e);

        return new TResponse()
        {
            Error = e.InnerException != null ? e.InnerException.Message : e.Message,
            Ok = false
        };
    }
}

如果您无法将调用链更改为异步,请改用同步 API。

【讨论】:

  • 好的,成功了,我想我明白了一点。我确实阅读了您之前提到的那篇文章,但我不太明白为什么这会阻止请求。像我以前那样做有什么意义?
  • 另外,是否可以从同步的旧版 VB.NET WebForm 调用 LoginAsync 方法作为非异步调用?我尝试只创建我的类的一个实例并在没有等待的情况下调用它,它似乎像以前一样死锁?我真的不想开始在遗留应用程序的任何地方添加异步......
  • @Raj 不,我绝对会推荐反对。 async 和 sync 方法通常有不同的代码执行路径,需要“复制”。你不应该这样做 "sync over async""async over sync"
  • @Raj 关于您的第一条评论,同步执行异步方法没有任何优势。这主要会导致您遇到刚刚经历的僵局。
猜你喜欢
  • 2015-04-26
  • 1970-01-01
  • 2014-02-14
  • 2018-07-09
  • 2014-05-15
  • 1970-01-01
  • 2012-12-07
  • 2023-03-08
相关资源
最近更新 更多