简体   繁体   中英

Ignoring the return value from an async Task method

Here's the scenario: In my WPF app I'd like to keep a loop running at all times that does various things. This pattern came to mind:

    void MainWindow_OnLoaded(object sender, RoutedEventArgs e)
    {
        SomeProcessAsync(); //throw away task
    }

    async Task SomeProcessAsync()
    {
        while (true)
        {
            DoSomething();

            await Task.Delay(1000);
        }
    }

The call triggers a warning since the return value is unused. What is the cleanest way to silence that warning?

#pragma warning disable 4014
            AddItemsAsync(); //throw away task
#pragma warning restore 4014

This works but it looks so nasty!

Btw, I also could have used a timer but I liked the simplicity of this loop.

As already mentioned in chris' answer, the right solution here is to turn the event handler into an async void method and then use await , so that exceptions are propagated correctly.

But if you really want to ignore the Task , then you can assign it to a variable:

var ignored = SomeProcessAsync();

Or in C# 7.0, you can use discard:

_ = SomeProcessAsync();

You can make the event handler async:

async void MainWindow_OnLoaded(object sender, RoutedEventArgs e)
{
    await SomeProcessAsync(); //throw away task
}

Normally, async void is bad, but it's necessary when an event handler is async and exceptions should be handled here instead of in whatever calls this. You can (and should) use the normal ConfigureAwait(false) if SomeProcessAsync doesn't need the UI context.

My solution is to silence the compiler warning with a little helper method that is reusable:

static class TaskHelpers
{
    /// <summary>Signifies that the argument is intentionally ignored.</summary>
    public static void DiscardTask(this Task ignored)
    {
    }
}

And the call looks like this:

AddItemsAsync().DiscardTask();

That's clean and self-documenting. Still looking for a better name for the helper.

Async-await uses threads from the thread pool. Although the number of threads in the thread pool is fairly large, and possibly adjustable, it is still a limited number of threads.

The threads in the thread pool are optimized for short living tasks. They start and finish fast, the results from these thread can be accessed fairly easily. But these advantages come with a cost. If not, all threads would be threads from the thread pool.

If you want to let your thread do something for a fairly long time, it is best to use a regular System.Threading.Thread, possibly wrapped in a System.ComponentModel.BackgroundWorker.

最好使用您的委托代码Task.Factory.StartNew(()=> {})创建任务;

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