代码之家  ›  专栏  ›  技术社区  ›  Vitor Durante

如何从我无法直接访问的线程捕获异常?

  •  1
  • Vitor Durante  · 技术社区  · 6 年前

    Start 方法运行 开始

    执行顺序如下所示。箭头指示在不同线程中运行的内容:

    -> MyService.Start -> pA.Start -> pb.Start -> return
                              \_> DoWork()  \
                                             \_> DoWork()
    

    既然都 DoWork()

    有什么建议可以避免这个问题吗?提前谢谢。

    以下代码是对实际代码的过度简化:

    public class MyService
    {
        private PluginA pA = new PluginA();
        private PluginB pB = new PluginB();
    
        // Windows Service runs Start when the service starts. It must return ASAP
        public void Start()
        {
            // try..catch doesn't capture PluginB's exception
            pA.Start();
            pB.Start();
        }
    
        // Windows Service runs Stop when the service Stops. It must return ASAP
        public void Stop()
        {
            pA.Stop();
            pB.Stop();
        }
    }
    
    // I have no control over how this is developed
    public class PluginA
    {
        private Timer _timer;
    
        public void Start()
        {
            _timer = new Timer(
                (e) => DoWork(),
                null,
                TimeSpan.Zero,
                TimeSpan.FromSeconds(10));
        }
    
        private void DoWork()
        {
            File.AppendAllText(
                "C:/log.txt",
                "hello" + Environment.NewLine);
        }
    
        public void Stop()
        {
            _timer.Change(Timeout.Infinite, 0);
        }
    }
    
    // I have no control over how this is developed
    public class PluginB
    {
        private Timer _timer;
    
        public void Start()
        {
            _timer = new Timer(
                (e) => DoWork(),
                null,
                TimeSpan.Zero,
                TimeSpan.FromSeconds(10));
        }
    
        private void DoWork()
        {
            File.AppendAllText(
                "C:/log.txt",
                "Goodbye" + Environment.NewLine);
    
            throw  new Exception("Goodbye");
        }
    
        public void Stop()
        {
            _timer.Change(Timeout.Infinite, 0);
        }
    }
    
    1 回复  |  直到 6 年前
        1
  •  3
  •   Nick    6 年前

    您也可以使用 AppDomain.UnhandledException Event

    请注意,您无法从此类异常中恢复。