How to call an async function in .NET without waiting for it

Refresh

March 2019

Views

54 time

-1

I have an async function in C# as follows:

    private static async Task AddEmoji(string emoji)
    {
       ...
    }

I have a situation where I'd like to call it but I don't want to wait for its result and I don't care if it works or not. What's the right way to go about this? I thought I could just call it without adding the async parameter:

AddEmoji("🏆");

... which works, but VS gives me a CS4014 compile warning, so I guess that's not right. I then tried to create a Task for it:

Task.Run(() => await AddEmoji("🏆"));

But that gives me an actual compile error:

Error CS4034 The 'await' operator can only be used within an async lambda expression. Consider marking this lambda expression with the 'async' modifier.

What's the right way to go about this?

3 answers

0

В вашем Task.Run (), то Await не идет внутри Func <>. Вы , как правило , ждут от самого (поставил задачу awaitперед Task.Run()), но я думаю , в вашем случае, вы можете опустить ОЖИДАНИЕ, чтобы не ждать , и игнорировать результаты:

Task.Run(() => AddEmjoi("🏆"))
-2

This does not apply to asp.net -- async void methods are not permitted in asp.net applications. Console, WPF, Winforms, etc, applications are fine however. See the comments for the full discussion.

The best thing to do is to await it inside an async void method.

The problem with just writing AddEmoji("🏆");, is: what happens if it fails? If an exception is thrown inside AddEmoji, then that exception is bundled up inside the Task which AddEmoji returned. However, because you threw that Task away, you'd never know. So AddEmoji can fail in a bad way, but you'd never know. This is why the compiler is giving you an error.

However, async void methods avoid that. If an exception is thrown inside an async void method, then that exception is re-thrown on the ThreadPool, which will bring down your application. You'll definitely know that something went wrong!

People advise against using async void methods, but they are perfect for fire-and-forget situations. The advice stems from people trying to use async void methods when they do want to know when the operation completed.

public async void AddEmojiImpl(string emoji) => await AddEmoji(emoji);

Or

public async void AddEmojiImpl(string emoji)
{
    try 
    {
        await AddEmojiImpl(emoji);
    }
    catch (EmojiAddException e)
    {
        // ...
    }
}

Local functions are particularly useful for this.

0

I don't want to wait for its result and I don't care if it works or not.

This is extremely unusual; the first thing to check is this assumption, that you literally don't need to know when it completes (or if it completes), and that you're OK with silently ignoring all exceptions. This also means that when your app exits, you're OK with this work never getting done (and again, you won't know because exceptions are ignored) - bearing in mind that in hosted scenarios like ASP.NET, you don't control when your app exits.

That said, you can do "fire and forget" as such:

var _ = AddEmoji("🏆");