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

时间:2015-10-05 21:07:36

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

我一直在玩基于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();

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

由于

1 个答案:

答案 0 :(得分:3)

此:

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

导致代码死锁。您与Task.Result await的调用同步阻止异步方法you shouldn't block on async code。相反,您需要使用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 }; } } 异步等待ir。这将有效地使您的调用链变得异步:

<rule
 enabled="true"
 stopProcessing="true"
 name="Route API calls to test server”>
 <match url="(api/.*)" />
 <action type="Rewrite" url="http://api.testdomain.com/{R:1}" />
</rule>

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