【问题标题】:Can't continue code execution when application in separate thread crashes当单独线程中的应用程序崩溃时无法继续执行代码
【发布时间】:2018-12-23 13:24:26
【问题描述】:

我正在处理其他一些非常不稳定且经常崩溃的应用程序。

这是我当前的设置,执行本身发生在 T:

    var threadEndEvent = new ManualResetEventSlim(false);
    var executionThread = new Thread(async () =>
                {
                    try
                    {
                        await T();
                    }
                    catch (Exception x)
                    {
                    //deal with exceptions...
                    }
                    finally
                    {
                    threadEndEvent.Set();
                    }
                }

我的定时器在超时时运行:

timer.Elapsed += (sender, args) =>
        {
        var result = Task.Run(() => executionThread.Abort()).Wait(new TimeSpan(0, 0, 30);
        //log if aborting was succesful and other info...
        threadEndEvent.Set();
        }

之后我会这样做:

    executionThread.Start();
    threadEndEvent.Wait(timeoutSpan)

最终,会发生以下两种情况之一:线程完成,或者在超时后尝试中止它,记录所有发生的事情并继续前进。

这在大多数情况下似乎工作正常,但是当我启动其他一些应用程序并且它崩溃时,显示标准错误,例如

"exe停止工作,Windows可以在线查看解决方法 问题”

中止永远不会发生,一切都挂了。

我以这种方式在 T 中启动该应用程序:

        var process = new Process
        {
            StartInfo =
            {
                //Specify path to exe, arguments, etc...
            }
        };
        process.Start();
        process.BeginOutputReadLine();
        process.BeginErrorReadLine();
        process.WaitForExit();

我知道WaitForExit 是线程阻塞,但是它在单独的线程executionThread 中执行,所以我不确定为什么执行会挂起。

我在这里缺少什么?无论发生什么,我如何让它在超时后继续运行?

【问题讨论】:

  • 我有点困惑。是您的线程有时会崩溃,还是您从该线程中启动的外部应用程序?这听起来更像是您正在启动一个应用程序。我不确定如何杀死线程会杀死外部应用程序,即使在超时之后也是如此。您能否再解释一下或展示您的线程代码/应用程序启动示例?
  • @pstrjds 更新了问题,我不想杀死外部应用程序,我只需要让我的代码在发生崩溃时不要挂断并继续前进。
  • 出现这个问题的时候有没有试过调试和破解?我想知道它是否可能被锁定在您的输出事件处理程序之一中。这是一个有点疯狂的猜测,但Process.WaitForExit 应该在应用程序崩溃时返回它将等待任何输出重定向处理程序完成。我认为您的线程中止代码仍会触发并终止该线程,但是当应用程序崩溃时,可能会有异步读取操作卡住。
  • @pstrjds 奇怪的是,从日志来看, timer.Elapsed 事件从一开始就不会触发 - 一切似乎都被卡住了。调试现在有问题,但一旦我能够做到,我会更新问题。
  • 根据您所描述的情况,除非您有其他东西阻塞了您的主线程,否则我完全被抛弃了。您确实对该事件进行了Wait 调用,但是您有超时,所以我希望即使计时器没有触发并中止线程并设置事件句柄,代码也会继续。您仍然应该继续通过该事件句柄。我怀疑发生了其他事情是您的应用程序崩溃并弹出该对话框吗?您是否在您的应用中设置了未处理的异常handlers

标签: c# process .net-core


【解决方案1】:

终于找到了解决办法。不幸的是,调试器不能正常工作,所以细节会很模糊。

一旦我开始深入挖掘,我发现T 是这样工作的:

var executingThread = new Thread(()=>{
//process code mentioned in question...
});
executingThread.Start();
executingThread.Join();

不知道为什么会这样,我正在处理未记录的遗留代码。

无论如何,一旦我删除了额外的线程代码,异常就会被正确捕获并且没有任何问题。

不确定为什么确切地创建额外线程会使异常无法捕获(当此代码在 .NET Framework 上运行时从未遇到过该问题),但如果您遇到类似问题,这可能是一个解决方案。

【讨论】:

    猜你喜欢
    • 2011-01-29
    • 1970-01-01
    • 1970-01-01
    • 2019-03-11
    • 1970-01-01
    • 2016-03-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多