以下是该场景:在我的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
这样可行,但看起来很讨厌!
不过,我也可以使用计时器,但我喜欢这个循环的简单性。答案 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; {});