0

So I have this method

         public async System.Threading.Tasks.Task<HttpResponseMessage> 
EmbedBIReport(string reportId)

And once it has gone off and done various async calls, such as

var authenticationAccessToken = 
  await _wrapperPowerBi.AuthenticationAccessToken(LookupValues.PbiResourceUrl,
  LookupValues.PbiClientId, credential)
  .ConfigureAwait(false);

it builds a response, like this

var embedConfig = new EmbedConfigModel
                {
                    EmbedToken = tokenResponse,
                    EmbedUrl = report.EmbedUrl,
                    Id = report.Id
                };                   

                var responseMessage = new ApiResponseMessageModel(
                    (int)BaseApiResponseCodeEnum.Ok,
                    LookupValues.PbiSuccessMessage);

                var response = _responseBuilder.BuidPowerBiResponse(
                    Request,
                    RequestId.Get,
                    HttpStatusCode.OK,
                    new List<ApiResponseMessageModel> { responseMessage },
                    embedConfig);

Debug writes confirm that it gets to this point, successfully building the response.

So far, so good.

Finally, we have

return response;

And this is where it gets weird...

Initially, it wasn't working at all when deployed to the Azure test environment. When I put .ConfigureAwait(false) on the end of every await, things were a lot better. But it doesn't actually return the response at the end, and the call times out.

Locally, obviously, it all works wonderfully (it wouldn't have been deplyed if it didn't!).

Does anyone have any suggestions as to what on Earth is going wrong?

Andrew Arnott
  • 216
  • 3
  • 8
  • 1
    It's returning an empty response because it isn't awaiting for the async task to complete – IronAces Apr 18 '18 at 15:00
  • How is `BuidPowerBiResponse` implemented? – Dan Wilson Apr 18 '18 at 15:00
  • BuidPowerBiResponse just takes a bunch of parameters and builds an HttpResponseMessage out of them. I have a habit of offloading building responses to dedicated classes. There is nothing cunning going on there, just a Request.CreateResponse with an object assembled from the parameters. – Andrew Arnott Apr 18 '18 at 15:04
  • @DanielShillcock it isn't returnign a response at all, not even an empty one. The three async calls made before the reponse builder is called are all awaited properly. In fact, the block containing the call to the response builder cannot be reached until these tasks have completed, because there is null checking on their results. This block will only be hit if we get a non-null response back from these other calls. Or have I misunderstood your point? – Andrew Arnott Apr 18 '18 at 15:07
  • @RacilHilan without *.ConfigureAwait(false)* it won't run at all once deployed to Azure. The original version didn't have this - and wrked fine on my local machine. This was added in an attempt to get it to work on Azure - it still works fine on my local machine. – Andrew Arnott Apr 18 '18 at 15:09
  • Let me be more specific... Before I added .ConfigureAwait(false), it was failing at the very first async call made inside the async method. After I added it, it goes all the way through and fails at the very last line. So you are right, it still doesn't work. But a lot more of it is executing successfully now. – Andrew Arnott Apr 18 '18 at 15:15
  • Perhaps I don't understand the use case, but I find it odd that you're returning `Task` rather than simply returning `HttpResponseMessage`. Have you tried making the method synchronous? – Dan Wilson Apr 18 '18 at 15:17
  • @RacilHilan there was nothing, though, no exception, just a timeout. – Andrew Arnott Apr 18 '18 at 15:25
  • @RacilHilan I did. "Debug writes confirm that it gets to this point, successfully building the response." and "it doesn't actually return the response at the end, and the call times out." – Andrew Arnott Apr 18 '18 at 15:35

1 Answers1

0

Thanks to the related links down the side, I found this - How would I run an async Task<T> method synchronously?

And picking up one of the suggestions there I used .GetAwaiter().GetResult() ont the calls to the methods that have to be async, and made the controller sync (as per Dan Wilson's suggestion).

This works.

Thanks to all for taking time to steer me through this.

Andrew Arnott
  • 216
  • 3
  • 8