Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

warning this call is not awaited, execution of the current method continues

Tags:

c#

async-await

People also ask

What happens if task is not awaited?

If you don't await the task or explicitly check for exceptions, the exception is lost. If you await the task, its exception is rethrown. As a best practice, you should always await the call. By default, this message is a warning.

What happens if I call async method without await?

What if you don't use await with async ? The call meant to be Asynchronous becomes Synchronous and would immediately impact the system scalability, as threads are now blocked, even worse for a long running IO operations.

When an asynchronous method is executed the code runs but nothing happens other than a compiler warning what is most likely causing the method to not return anything?

When a asynchronous method is executed, the code runs but nothing happens other than a compiler warning. What is most likely causing the method to not return anything? (A) The return yield statement is missing at the end of the method.

Can you use async without await C?

Consider Using async without await. think that maybe you misunderstand what async does. The warning is exactly right: if you mark your method async but don't use await anywhere, then your method won't be asynchronous. If you call it, all the code inside the method will execute synchronously.


If you really don't need the result, you can simply change the GetNameAsync's signature to return void:

public static async void GetNameAsync()
{
    ...
}

Consider to see answer to a related question: What's the difference between returning void and returning a Task?

Update

If you need the result, you can change the GetNameAsync to return, say, Task<string>:

public static async Task<string> GetNameAsync()
{
    string firstname = await PromptForStringAsync("Enter your first name: ");
    string lastname = await PromptForStringAsync("Enter your last name: ");
    return firstname + lastname;
}

And use it as follows:

public static void DoStuff()
{
    Task<string> task = GetNameAsync();

    // Set up a continuation BEFORE MainWorkOfApplicationIDontWantBlocked
    Task anotherTask = task.ContinueWith(r => {
            Console.WriteLine(r.Result);
        });

    MainWorkOfApplicationIDontWantBlocked();

    // OR wait for the result AFTER
    string result = task.Result;
}

I'm quite late to this discussion, but there is also the option to use the #pragma pre-processor directive. I have some async code here and there that I explicitly do not want to await in some conditions, and I dislike warnings and unused variables just like the rest of you:

#pragma warning disable 4014
SomeMethodAsync();
#pragma warning restore 4014

The "4014" comes from this MSDN page: Compiler Warning (level 1) CS4014.

See also the warning/answer by @ryan-horath here https://stackoverflow.com/a/12145047/928483.

Exceptions thrown during an async call that is not awaited will be lost. To get rid of this warning, you should assign the Task return value of the async call to a variable. This ensures you have access to any exceptions thrown, which will be indicated in the return value.

Update for C# 7.0

C# 7.0 adds a new feature, discard variables: Discards - C# Guide, which can also help in this regard.

_ = SomeMethodAsync();

I'm not particularly fond of the solutions that either assign the task to an unused variable, or changing the method signature to return void. The former creates superfluous, non-intuitive code, while the latter may not be possible if you're implementing an interface or have another usage of the function where you want to use the returned Task.

My solution is to create an extension method of Task, called DoNotAwait() that does nothing. This will not only suppress all warnings, ReSharper or otherwise, but makes the code more understandable, and indicates to future maintainers of your code that you really intended for the call to not be awaited.

Extension method:

public static class TaskExtensions
{
    public static void DoNotAwait(this Task task) { }
}

Usage:

public static void DoStuff()
{
    GetNameAsync().DoNotAwait();
    MainWorkOfApplicationIDontWantBlocked();
}

Edited to add: this is similar to Jonathan Allen's solution where the extension method would start the task if not already started, but I prefer to have single-purpose functions so that the caller's intent is completely clear.


async void IS BAD!

  1. What's the difference between returning void and returning a Task?
  2. https://jaylee.org/archive/2012/07/08/c-sharp-async-tips-and-tricks-part-2-async-void.html

What I suggest is that you explicitly run the Task via an anonymous method...

e.g.

public static void DoStuff()
{
    Task.Run(async () => GetNameAsync());
    MainWorkOfApplicationIDontWantBlocked();
}

Or if you did want it to block you can await on the anonymous method

public static void DoStuff()
{
    Task.Run(async () => await GetNameAsync());
    MainWorkOfApplicationThatWillBeBlocked();
}

However, if your GetNameAsync method has to interact with UI or even anything UI bound, (WINRT/MVVM, I'm looking at you), then it gets a little funkier =)

You'll need to pass the reference to the UI dispatcher like this...

Task.Run(async () => await GetNameAsync(CoreApplication.MainView.CoreWindow.Dispatcher));

And then in your async method you'll need to interact with your UI or UI bound elements thought that dispatcher...

dispatcher.RunAsync(CoreDispatcherPriority.Normal, () => {  this.UserName = userName; });

This is what I'm currently doing:

SomeAyncFunction().RunConcurrently();

Where RunConcurrently is defined as...

 /// <summary> 
 /// Runs the Task in a concurrent thread without waiting for it to complete. This will start the task if it is not already running. 
 /// </summary> 
 /// <param name="task">The task to run.</param> 
 /// <remarks>This is usually used to avoid warning messages about not waiting for the task to complete.</remarks> 
 public static void RunConcurrently(this Task task) 
 { 
     if (task == null) 
         throw new ArgumentNullException("task", "task is null."); 

     if (task.Status == TaskStatus.Created) 
         task.Start(); 
 } 

https://github.com/docevaad/Anchor/blob/master/Tortuga.Anchor/Tortuga.Anchor.source/shared/TaskUtilities.cs

https://www.nuget.org/packages/Tortuga.Anchor/