gpt4 book ai didi

c# - Task.Run 和 Task.Factory.StartNew 之间不同的异常处理

转载 作者:可可西里 更新时间:2023-11-01 08:07:03 27 4
gpt4 key购买 nike

我在使用 Task.Factory.StartNew 并 try catch 抛出的 exception 时遇到问题。在我的应用程序中,我有一个长时间运行的任务,我想将其封装在 Task.Factory.StartNew(.., TaskCreationOptions.LongRunning);

但是,当我使用 Task.Factory.StartNew 时,异常没有被捕获。然而,当我使用 Task.Run 时,它的工作方式与我预期的一样,我认为它只是 Task.Factory.StartNew 的包装器(根据例如 this MSDN article ) .

此处提供了一个工作示例,不同之处在于使用 Task.Run 时将异常写入控制台,但使用 Factory.StartNew 时则不会。

我的问题是:
如果我有一个可能抛出异常的 LongRunning 任务,我应该如何在调用代码中处理它们?

private static void Main(string[] args)
{
Task<bool> t = RunLongTask();
t.Wait();
Console.WriteLine(t.Result);
Console.ReadKey();
}

private async static Task<bool> RunLongTask()
{
try
{
await RunTaskAsync();
}
catch (Exception e)
{
Console.WriteLine(e);
return false;
}
Console.WriteLine("success");
return true;
}

private static Task RunTaskAsync()
{
//return Task.Run(async () =>
// {
// throw new Exception("my exception");
// });
return Task.Factory.StartNew(
async () =>
{
throw new Exception("my exception");
});

}

最佳答案

你的问题是StartNew不像Task.Run那样工作与 async代表们。 StartNew 的返回类型是Task<Task> (可转换为 Task )。 “外”Task表示方法的开始,“内部”Task表示方法的完成(包括任何异常)。

进入内部Task , 你可以使用 Unwrap .或者你可以只使用 Task.Run而不是 StartNew对于 async代码。 LongRunning只是一个优化提示,实际上是可选的。 Stephen Toub has a good blog post on the difference between StartNew and Run and why Run is (usually) better for async code.

来自@usr 评论的更新: LongRunning只适用于async的开头方法(直到第一个不完整的操作被 await 编辑)。所以使用 Task.Run 几乎肯定更好在这种情况下。

关于c# - Task.Run 和 Task.Factory.StartNew 之间不同的异常处理,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14729736/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com