当前位置: 首页 > 编程语言 > C#

Task.Run和Task.Factory.StartNew异常处理的不同分享

时间:2023-04-10 21:20:46 C#

Task.Run和Task.Factory.StartNew在异常处理上的不同我在抛出异常时遇到了一个问题。在我的应用程序中,我有一个长时间运行的任务,我想将其包装在Task.Factory.StartNew(..,TaskCreationOptions.LongRunning);但是,当我使用Task.Factory.StartNew时,没有捕获到异常。但是,当我使用Task.Run时,它会像我期望的那样工作Task.Run,??我认为它只是Task.Factory.StartNew的包装器(根据例如这篇MSDN文章)。这里提供了一个工作示例,不同之处在于使用Task.Run时将异常写入控制台,而使用Factory.StartNew时则不会。我的问题是:如果我有一个可以抛出异常的LongRunning任务,我应该如何在调用代码中处理它们?privatestaticvoidMain(string[]args){Taskt=RunLongTask();t.等待();Console.WriteLine(t.Result);控制台.ReadKey();}privateasyncstaticTaskRunLongTask(){try{awaitRunTaskAsync();}catch(Exceptione){Console.WriteLine(e);返回假;}Console.WriteLine("成功");返回真;}privatestaticTaskRunTaskAsync(){//returnTask.Run(async()=>//{//thrownewException("myexception");//});返回任务。工厂。StartNew(async()=>{thrownewException("myexception");});您的问题是StartNew不使用像Task.Run这样的异步委托。StartNew的返回类型是Task(可以转换为Task)。“外部”Task表示方法的开始,“内部”Task表示方法的完成(包括任何异常)。要进入Task,您可以使用Unwrap。或者您可以使用Task.Run而不是StartNew来处理异步代码。LongRunning只是一个优化提示,实际上是可选的。StephenToub有一篇博文介绍StartNew和Run之间的区别,以及为什么Run(通常)更适合异步代码。从下面@usr的评论更新:LongRunning仅在异步方法开始时有效(直到第一个未完成的await编辑)。所以在这种情况下使用Task.Run几乎肯定更好。我会在答案中添加一些评论,因为它们对我们有帮助:LongRunning在实践中与强制创建新线程完全相同。并且您的异步方法可能不会在该线程上运行很长时间(它在第一个等待点被取消)。在这种情况下,您不需要LongRunning。异步方法运行多长时间并不重要。线程在第一次等待时被销毁(对未完成的任务进行操作)。编译器能否以任何方式使用此提示?编译器通常无法以任何主要方式分析您的代码。此外,编译器对TPL一无所知。TPL是一个图书馆。而这个库总会开启一个新的线程。如果您的任务几乎总是在许多秒内消耗100%CPU,或者以非常高的概率阻塞许多秒,请指定LongRunning。我猜你不想在这里使用LongRunning,因为如果你是阻塞的,为什么一开始就使用async?async不是阻塞而是中断线程。当您第一次打开任务时,您应该能够:awaitRunTaskAsync().Unwrap();或者:以上就是C#学习教程:Task.Run和Task.Factory.StartNew之间的异常处理了所有不同份额的内容,如果对大家有用还有需要了解更多的C#学习教程,希望大家会多加注意——awaitawaitRunTaskAsync();如需转载请注明出处: