0

While trying to check the result of an asynchronous method I'm getting the below error.

Neither I tried await container.ExistsAsync().Result nor bool result = await container.GetAwaiter().GetResult(); worked.

Where am I going wrong?

[TestMethod]
public async Task StorageAccountConnectionTest()
{
    var storageCredentials = new StorageCredentials(_mockFuncXTransConfiguration.Object.StorageAccountName, _mockFuncXransConfiguration.Object.StorageAccountKey);
    var cloudStorageAccount = new CloudStorageAccount(storageCredentials, true);
    var cloudBlobClient = cloudStorageAccount.CreateCloudBlobClient();
    var container = cloudBlobClient.GetContainerReference(_mockFuncXTransConfiguration.Object.BlobName);
    bool result = await container.ExistsAsync().Result;
    Assert.AreEqual(true, result);
}

enter image description here

The Inquisitive Coder
  • 1,085
  • 3
  • 20
  • 43
  • Either `await` the result asynchronously or `GetAwaiter().GetResult()` it synchronously -- not both. (In this case there seems to be no reason at all to go synchronous.) – Jeroen Mostert Mar 02 '20 at 14:12
  • You can't `await Task.Result`, you just use `await Task`, so use `bool result = await container.ExistsAsync();` – Lasse V. Karlsen Mar 02 '20 at 14:20
  • 1
    Wrong duplicate link. This is not about Task not having GetAwaiter, it is as the question states, about `bool` not having GetAwaiter, and that is because this is a hodge podge of synchronous and asynchronous code. `ExistsAsync().Result` will force an immediate block and wait for the result to be available, with all the possibilities of deadlock that can occur. There is no *need* for `await` here, or rather, there should not be a call to `Result` here, and instead the task from `ExistsAsync()` should be awaited to get the boolean result. The duplicate is about something quite different. – Lasse V. Karlsen Mar 02 '20 at 14:32

1 Answers1

7

You're currently trying to wait the result of the task:

bool result = await container.GetAwaiter().GetResult().Result;

Which is redundant, but also a deadlock problem waiting to happen. (Almost never call .Result directly.) Instead, await the task which produces the result:

bool result = await container.GetAwaiter().GetResult();

Edit: As pointed out in the comments below, I'd missed that the container is already a task. Since the whole method is already async, you can skip all of the GetAwaiter stuff and just await it directly:

bool result = await container;

Edit: As further pointed out in comments, it looks like the code you provided doesn't match the code you're actually using in the screen shot. The container itself isn't the task, but has a method which returns the task you want:

bool result = await container.ExistsAsync();
David
  • 208,112
  • 36
  • 198
  • 279
  • 3
    The method is async already - there's no need to use .GetAwaiter.GetResult() at all. It can simply be awaited. – mason Mar 02 '20 at 14:12
  • 6
    Or she could just await the task : `bool result = await container` – RB. Mar 02 '20 at 14:12
  • @David, could you point out where to read about `GetAwaiter().GetResult();` should be used instead of `Result`? From MS help for `TaskAwaiter.GetResult`: This API supports the product infrastructure and is not intended to be used directly from your code. – Miamy Mar 02 '20 at 14:23
  • 1
    FYI, the code should be `await container.ExistsAsync();`. The example code is all messed up but the included screenshot shows the appropriate method call that returns `Task` – maccettura Mar 02 '20 at 14:37
  • Yeah actually your last two bits of code would not compile, this needs to be fixed – maccettura Mar 02 '20 at 14:54
  • 1
    @maccettura: Should be fixed now. Looks like a pretty good example of a case where the OP artificially modified code while posting it, instead of just copying/pasting. Thanks for catching it! – David Mar 02 '20 at 15:28