Reputation: 907
I've been playing around with creating a REST wrapper based on https://github.com/JeffGos/urbanairsharp.
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
};
}
}
I am able to call the Login method absolutely fine from a console app but if I call it from an MVC controller, it steps through the code fine but never passes the line
var requestTask = request.ExecuteAsync();
I have read around the subject but dont quite understand how I can use these methods from a web app? The Login() method is not async so I dont see why it would fail from my MVC action (also non-async)?
Thanks
Upvotes: 1
Views: 1224
Reputation: 149538
This:
var requestTask = request.ExecuteAsync();
return requestTask.Result;
Is causing your code to deadlock. You're blocking an async method synchronously with the call to Task.Result
That's why you shouldn't block on async code. Instead, you need to asynchronously wait on ir with await
. This will effectively make your call chain become async as well:
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
};
}
}
In case you can't change your call chain to become asynchronous, use a synchronous API instead.
Upvotes: 4