我正在尝试重新创建导致此异常的条件:
System.AggregateException: A Task's exception(s) were not observed
either by Waiting on the Task or accessing its Exception property.
As a result, the unobserved exception was rethrown by the finalizer thread.`
我写了这个程序,认为我会引起异常,但事实并非如此:
using System;
using System.Threading.Tasks;
namespace SomeAsyncStuff
{
class Program
{
static void Main(string[] args)
{
Task.Factory.StartNew(() => { throw new NullReferenceException("ex"); });
GC.Collect();
Console.WriteLine("completed");
}
}
}
在我的实际应用程序中,我使用TPL并且我没有编写正确的异常处理代码。结果我得到了那个例外。现在,我正在尝试在单独的程序中重新创建相同的条件,以试验未观察到的异常。
答案 0 :(得分:4)
您可能需要在GC.Collect()之后添加对GC.WaitForPendingFinalizers()的调用,因为终结器在他们自己的线程上运行。
答案 1 :(得分:3)
TaskExceptionHolder
的终结器抛出异常,因此终结器线程必须在抛出此异常之前运行。正如乔希指出的那样,你可以通过拨打CG.WaitForPedingFinalizers()
来等待。
请注意,当前的异步CTP中已更改此行为。我在今年早些时候在TechEd Europe上与PFX团队的Stephen Toub谈过这个问题,他表示他们必须改变它以使新的异步功能正常工作。因此,尽管对框架的下一个版本说什么还为时尚早,但在即将发布的版本中,这种行为很可能会发生变化。
答案 2 :(得分:1)
任务myTask = Task.Factory.StartNew(()=> { 抛出新的NullReferenceException(“ex”); }); //给一些时间完成任务 myTask.Wait();
答案 3 :(得分:0)
我很惊讶您在任务完成后没有尝试正确调用代码,因为谁说任何进程将在3秒内完成?不仅如此,它还会占用其他进程3秒钟。我将使用ContinueWith()任务方法替换该实现,以在任务完成后调用GC。
Task.Factory
.StartNew(() => { throw new NullReferenceException("ex"); })
.ContinueWith(p => GC.Collect());
如果需要阻塞直到它完成(对于您用于调试的示例代码),您还可以在启动任务后执行WaitOne并让ContinueWith()发出等待处理程序的信号。如果您必须在生产代码中执行此操作,那么您尝试完成的任务实际上是同步的,您根本不需要担心使用任务。
答案 4 :(得分:-1)
我是OP。我测试了GC.WaitForPendingFinalizers(),但它没有帮助重新创建异常。问题是在任务开始之前执行了GC.Collect()。
这是重新创建例外的正确代码:
using System;
using System.Threading;
using System.Threading.Tasks;
namespace SomeAsyncStuff
{
class Program
{
static void Main(string[] args)
{
Task.Factory.StartNew(() => { throw new NullReferenceException("ex"); });
// give some time to the task to complete
Thread.Sleep(3000);
GC.Collect();
// GC.WaitForPendingFinalizers();
Console.WriteLine("completed");
}
}
}
答案 5 :(得分:-1)
重新创建错误的最简单方法是等待任务完成。
Task task = Task.Factory.StartNew(() => { throw new NullReferenceException("ex"); });
//this is where the exception will be thrown
task.Wait();
调用wait将阻止调用,直到任务完成执行。