根据我的研究,我学到了以下内容:
TaskScheduler.UnobservedTaskException必须等待该任务被垃圾收集,然后该任务的未被观察到的异常将冒泡到该UnobservedTaskException事件.Task.Wait()它,它永远不会被调用,因为你正在阻止来自Task的即将发生的结果,因此异常将被抛出Task.Wait()而不是冒泡到UnobservedException事件.GC.Collect()手动调用通常是一个坏主意,除非你确切地知道你正在做什么,因此在这种情况下确认事情是好的,但不能作为问题的正确解决方案.问题
如果我的应用程序在垃圾收集器启动之前退出,我绝对100%无法UnobservedTaskException触发我的事件.
请注意以下代码:
class Program
{
static void Main(string[] args)
{
TaskScheduler.UnobservedTaskException += TaskScheduler_UnobservedTaskException;
Task.Factory.StartNew(() =>
{
Console.WriteLine("Task started.");
throw new Exception("Test Exception");
});
Thread.Sleep(1000);
//GC.Collect();
//GC.WaitForPendingFinalizers();
}
static void TaskScheduler_UnobservedTaskException(object sender, UnobservedTaskExceptionEventArgs e)
{
File.WriteAllText(@"C:\data\TestException.txt", e.Exception.ToString());
Console.WriteLine("UNOBSERVED EXCEPTION");
}
}
Run Code Online (Sandbox Code Playgroud)
没有写入异常文件,也没有任何内容写入控制台.在应用程序退出后10-15分钟甚至更长时间可以继续,但我仍然看不到我的应用程序的遗骸被垃圾收集的证据.您可能会问,为什么不在退出时收集?好吧,我的真实场景是我的异常陷阱在Windows服务中托管的WCF服务内运行.当Windows服务关闭(因此手动调用GC.Collect())时,我无法陷阱,因为就我所见,没有任何事件.
我哪里错了?我如何确保如果WCF服务内部的某些内容最终会破坏我的Windows服务,那么我有机会在服务崩溃之前记录异常?
我试图尽可能地保持(我的beta版本)应用程序运行,所以我在发生一些严重错误的情况下也放置了另一个try-catch内部Program.cs并且意外地关闭了应用程序.并且在catch我重写了Application.Run()方法以便应用程序可以在因任何原因被终止后自行恢复.
针对这种特定情况制定此类计划是否正确?
如果不对,那么为了保持程序运行,还有什么建议?
这是展示我的意思的示例代码:
using System;
using System.Collections.Generic;
using System.Windows.Forms;
using Hossein;
using Pishro.Classes;
namespace Pishro
{
static class Program
{
/// <summary>
/// The main entry point for the application.
/// </summary>
[STAThread]
static void Main()
{
try
{
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
Application.Run(new frmMain());
}
catch(Exception exc)
{
API.SaveAndShowLog(exc);
Application.Run(new frmMain());
}
}
}
}
Run Code Online (Sandbox Code Playgroud)