相关疑难解决方法(0)

永远不会调用TaskScheduler.UnobservedTaskException

根据我的研究,我学到了以下内容:

  1. TaskScheduler.UnobservedTaskException必须等待该任务被垃圾收集,然后该任务的未被观察到的异常将冒泡到该UnobservedTaskException事件.
  2. 如果你正在使用Task.Wait()它,它永远不会被调用,因为你正在阻止来自Task的即将发生的结果,因此异常将被抛出Task.Wait()而不是冒泡到UnobservedException事件.
  3. 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服务,那么我有机会在服务崩溃之前记录异常?

.net garbage-collection exception

13
推荐指数
2
解决办法
4401
查看次数

是否可以将Application.Run()方法放入catch中以避免应用程序终止?

我试图尽可能地保持(我的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)

c# try-catch

3
推荐指数
1
解决办法
2009
查看次数

标签 统计

.net ×1

c# ×1

exception ×1

garbage-collection ×1

try-catch ×1