简体   繁体   中英

Calling method from MVC controller hangs due to async await

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

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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM