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

时间:2018-12-07 14:51:34

标签: c# .net .net-core

我已经开发了能够运行一些插件的Windows服务。由于其性质,在开发Windows服务时,Start和Stop方法应运行并尽快返回。 Start方法从所有插件运行Start方法,这也不应阻止执行。在此示例中,两个插件都实例化了一个Threading.Timer,它在后台运行。

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

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

由于两个DoWork()都在计时器中运行,因此如果发生异常,我将无法捕获它。如果我可以修改PluginA和PluginB,但可以避免,则很容易避免。

关于如何避免此问题的任何建议?预先感谢。

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

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 个答案:

答案 0 :(得分:3)

您也可以使用AppDomain.UnhandledException Event

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