在 dotnetcoreapp2.0 中使用 UnobservedTaskException 处理程序
Using the UnobservedTaskException handler in dotnetcoreapp2.0
以下代码,当 运行 在 netcoreapp2.0 应用程序中时,似乎并没有最终抛出 UnobservedTaskException
using System;
using System.Threading;
using System.Threading.Tasks;
namespace ConsoleApp3 {
class Program {
public static void Main(string[] args) {
TaskScheduler.UnobservedTaskException += (s, e) => {
/// Try to crash the application - we wanna nail unobserved exceptions dead.
/// Unfortunately, this code never seems to run.
Console.WriteLine("UnobservedTaskException thrown.");
throw e.Exception;
};
var t = Task.Run(() => {
throw new NotImplementedException();
});
while (!t.IsFaulted)
Thread.Sleep(1);
t = null;
Console.WriteLine("Task is faulted.");
GC.Collect();
GC.WaitForPendingFinalizers();
Console.ReadKey();
}
}
}
这是项目文件。如何让 UnobservedTaskException
处理程序被解雇?
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>netcoreapp2.2</TargetFramework>
<LangVersion>7.3</LangVersion>
</PropertyGroup>
</Project>
在其他 Whosebug 帖子中,我看到了在项目文件中使用以下代码片段的建议,但它仅适用于 .net Framework 4.0+ 项目。如果 .netcore 项目文件有等效项,那可能就是我需要知道的。
<runtime>
<ThrowUnobservedTaskExceptions enabled="true"/>
</runtime>
还没有答案,但我觉得有点有趣。我正在查看 GitHub 上的源代码。调用事件处理程序的唯一位置是 TaskScheduler
class.
中的 PublishUnobservedTaskException
方法
唯一调用 PublishUnobservedTaskException
的地方来自 finalizer of TaskExceptionHolder
。但是,在调用 PublishUnobservedTaskException
之前必须满足一些条件,如您在该源代码中所见。
我已经 enabled debugging the .NET source code,但我得到的 TaskExceptionHolder
版本与 GitHub 上的不同,它显然与我尝试的断点不匹配制作。所以我不能确切地确认为什么它没有被调用,而且我今晚 运行 没时间了。
甚至可能值得为此 over at GitHub 创建一个问题。
我遇到了同样的问题。只需在 RELEASE 模式下尝试 运行。我对其进行了测试,它正在与控制台应用程序 .net 核心版本 2.2 一起使用。
internal class Program
{
private static void Main(string[] args)
{
// REMEMBER TO RUN IN RELEASE MODE
var handler = new EventHandler<UnobservedTaskExceptionEventArgs>(Unobserved);
TaskScheduler.UnobservedTaskException += handler;
Task.Run(() => { Console.WriteLine("task 1"); throw new Exception("TASK 1 EXCEPTION"); });
Task.Run(() => { Console.WriteLine("task 2"); throw new Exception("TASK 2 EXCEPTION"); });
Thread.Sleep(1000);
GC.Collect();
GC.WaitForPendingFinalizers();
GC.Collect();
Thread.Sleep(1000);
Console.ReadKey();
}
private static void Unobserved(object o, UnobservedTaskExceptionEventArgs e)
{
e.SetObserved(); // optional
foreach (var ex in e.Exception.InnerExceptions)
{
Console.WriteLine(ex.Message);
}
}
}
以下代码,当 运行 在 netcoreapp2.0 应用程序中时,似乎并没有最终抛出 UnobservedTaskException
using System;
using System.Threading;
using System.Threading.Tasks;
namespace ConsoleApp3 {
class Program {
public static void Main(string[] args) {
TaskScheduler.UnobservedTaskException += (s, e) => {
/// Try to crash the application - we wanna nail unobserved exceptions dead.
/// Unfortunately, this code never seems to run.
Console.WriteLine("UnobservedTaskException thrown.");
throw e.Exception;
};
var t = Task.Run(() => {
throw new NotImplementedException();
});
while (!t.IsFaulted)
Thread.Sleep(1);
t = null;
Console.WriteLine("Task is faulted.");
GC.Collect();
GC.WaitForPendingFinalizers();
Console.ReadKey();
}
}
}
这是项目文件。如何让 UnobservedTaskException
处理程序被解雇?
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>netcoreapp2.2</TargetFramework>
<LangVersion>7.3</LangVersion>
</PropertyGroup>
</Project>
在其他 Whosebug 帖子中,我看到了在项目文件中使用以下代码片段的建议,但它仅适用于 .net Framework 4.0+ 项目。如果 .netcore 项目文件有等效项,那可能就是我需要知道的。
<runtime>
<ThrowUnobservedTaskExceptions enabled="true"/>
</runtime>
还没有答案,但我觉得有点有趣。我正在查看 GitHub 上的源代码。调用事件处理程序的唯一位置是 TaskScheduler
class.
PublishUnobservedTaskException
方法
唯一调用 PublishUnobservedTaskException
的地方来自 finalizer of TaskExceptionHolder
。但是,在调用 PublishUnobservedTaskException
之前必须满足一些条件,如您在该源代码中所见。
我已经 enabled debugging the .NET source code,但我得到的 TaskExceptionHolder
版本与 GitHub 上的不同,它显然与我尝试的断点不匹配制作。所以我不能确切地确认为什么它没有被调用,而且我今晚 运行 没时间了。
甚至可能值得为此 over at GitHub 创建一个问题。
我遇到了同样的问题。只需在 RELEASE 模式下尝试 运行。我对其进行了测试,它正在与控制台应用程序 .net 核心版本 2.2 一起使用。
internal class Program
{
private static void Main(string[] args)
{
// REMEMBER TO RUN IN RELEASE MODE
var handler = new EventHandler<UnobservedTaskExceptionEventArgs>(Unobserved);
TaskScheduler.UnobservedTaskException += handler;
Task.Run(() => { Console.WriteLine("task 1"); throw new Exception("TASK 1 EXCEPTION"); });
Task.Run(() => { Console.WriteLine("task 2"); throw new Exception("TASK 2 EXCEPTION"); });
Thread.Sleep(1000);
GC.Collect();
GC.WaitForPendingFinalizers();
GC.Collect();
Thread.Sleep(1000);
Console.ReadKey();
}
private static void Unobserved(object o, UnobservedTaskExceptionEventArgs e)
{
e.SetObserved(); // optional
foreach (var ex in e.Exception.InnerExceptions)
{
Console.WriteLine(ex.Message);
}
}
}