忽略异步任务方法的返回值

时间:2017-03-16 15:29:40

标签: c# async-await compiler-warnings

以下是该场景:在我的WPF应用程序中,我希望始终保持循环运行以执行各种操作。我想到了这种模式:

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

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

            await Task.Delay(1000);
        }
    }

由于返回值未使用,该调用会触发警告。沉默警告的最简洁方法是什么?

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

这样可行,但看起来很讨厌!

不过,我也可以使用计时器,但我喜欢这个循环的简单性。

5 个答案:

答案 0 :(得分:6)

您可以使事件处理程序异步:

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

通常情况下,async void很糟糕,但是当事件处理程序是异步时需要处理,并且应该在这里处理异常而不是在任何调用中。如果ConfigureAwait(false)不需要UI上下文,您可以(并且应该)使用普通SomeProcessAsync

答案 1 :(得分:5)

正如在chris的回答中已经提到的,这里正确的解决方案是将事件处理程序转换为async void方法,然后使用await,以便正确传播异常。

但如果你真的想忽略Task,那么你可以将它分配给一个变量:

var ignored = SomeProcessAsync();

或者在C#7.0中,您可以使用discard:

_ = SomeProcessAsync();

答案 2 :(得分:1)

我的解决方案是使用可重用的小辅助方法使编译器警告静音:

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

电话看起来像这样:

AddItemsAsync().DiscardTask();

那是干净的,自我记录的。仍在为助手寻找一个更好的名字。

答案 3 :(得分:-1)

Async-await使用线程池中的线程。虽然线程池中的线程数量相当大,并且可能是可调整的,但它仍然是有限数量的线程。

线程池中的线程针对短生命任务进行了优化。它们快速启动和完成,这些线程的结果可以很容易地访问。但这些优势伴随着成本。如果不是,所有线程都将是线程池中的线程。

如果你想让你的线程在相当长的时间内做某事,最好使用常规的System.Threading.Thread,可能包含在System.ComponentModel.BackgroundWorker中。

答案 4 :(得分:-3)

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