从MVC控制器调用方法由于异步等待而挂起

本文关键字:异步 等待 挂起 于异步 控制器 MVC 调用 方法 | 更新日期: 2023-09-27 18:16:04

我一直在尝试创建基于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动作失败(也非异步)?

谢谢

从MVC控制器调用方法由于异步等待而挂起

This:

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

导致代码死锁。你正在阻塞异步方法与Task.Result的调用同步,这就是为什么你不应该阻塞异步代码。相反,您需要使用await异步等待它。这将有效地使您的调用链也变成异步的:

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代替。