我一直在玩基于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动作(也是非异步)而失败?
由于
答案 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。