【问题标题】:Is it Ok to put Application.Run() method in a catch to avoid application termination?是否可以将 Application.Run() 方法放入 catch 以避免应用程序终止?
【发布时间】:2012-09-16 18:49:27
【问题描述】:

我试图让(我的测试版)应用程序尽可能地运行,所以我在Program.cs 中放置了另一个try-catch,以防出现一些严重错误并意外关闭应用程序。并且在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());
            }
        }
    }
  }

【问题讨论】:

  • 如果您需要保持运行 - 我向您提出这个问题.. 如果再次发生异常怎么办?
  • 如果应用程序因错误而退出,IMO 您应该记录异常并向描述错误的用户显示MessageBox
  • 在您执行此操作之前,请阅读此内容。 stackoverflow.com/questions/10061287/…
  • @BugFinder:这就是我首先问这个问题的原因。
  • @MatthewRz:使用 SaveAndShowLog() 方法已经完成。同时所有发生的错误日志都显示在管理部分,我只需要一种方法在程序继续进行时尽可能多地进行测试工作。

标签: c# try-catch


【解决方案1】:

全局处理异常是记录和警报的好主意。

像您这样的自动重启策略可能很有用,是的。但是存在一个风险:如果崩溃损坏了全局数据结构,重新启动应用程序可能会产生不可预知的结果,例如静默数据损坏。例如,文件可能仍处于打开和锁定状态。锁可能还没有被释放。静态变量可能处于未定义状态。流氓线程可能仍在运行,却不知道应用程序 UI 已被破坏。

我建议您通过启动应用程序的新进程来重新启动应用程序。让旧进程死掉。

【讨论】:

  • 谢谢,所以你建议改用Application.Restart()
  • @Hossein yes Application.Restart 是个好主意。如果由于任何原因这不起作用,您也可以使用Process.Start
【解决方案2】:

我认为您的问题涉及更深层次的问题。我应该抓住所有例外吗? 为了继续前进,您可以全部捕获它们。但所有那些您不期望或不知道的可能异常都可能是错误。

也许您应该尝试在您的应用中实施更好的错误处理方法。所以所有的异常都是已知的或预期的。

【讨论】:

  • 我的应用程序内部确实有错误处理,我真的在任何地方都尝试过,但是目前我无法模拟自己的情况,因为应用程序很大并且有很多部分与用户交互,这就是为什么我尝试记录错误并同时让应用程序运行以进行更多测试
  • 我想说的是,如果您使用一般错误处理来记录和检测您的应用程序可能存在的问题,那也没关系。但是,一旦您意识到异常,请更正它们,因为它们可能是错误。
【解决方案3】:

不要将try catch 包裹在您的应用程序运行方法周围,而是考虑使用事件处理异常。

static void Main()
{
  AppDomain.CurrentDomain.UnhandledException += new UnhandledExceptionEventHandler(CurrentDomain_UnhandledException);
  Application.ThreadException += new System.Threading.ThreadExceptionEventHandler(Application_ThreadException);
  Application.EnableVisualStyles();
  Application.SetCompatibleTextRenderingDefault(false);
  Application.Run(new Form1());
}

static void Application_ThreadException(object sender, System.Threading.ThreadExceptionEventArgs e)
{
  MessageBox.Show("Exception handled");
}

static void CurrentDomain_UnhandledException(object sender, UnhandledExceptionEventArgs e)
{

}

主要是线程异常是您想要的,但理想情况下 - 您希望设置某种形式的日志记录/向用户标记错误并仍然处置程序,因为它可能导致程序继续处于不合适的状态.请在您的表单和点击事件中添加一个按钮throw new Exception("");,然后应该会显示消息框。

【讨论】:

  • @Downvoter 请解释一下 - 只要我知道我在未来做错了什么,不要介意投反对票。
猜你喜欢
  • 1970-01-01
  • 2019-09-01
  • 1970-01-01
  • 2020-05-12
  • 1970-01-01
  • 2013-09-17
  • 1970-01-01
  • 1970-01-01
  • 2018-10-04
相关资源
最近更新 更多