【问题标题】:How do I stop running code from executing?停止执行 C# 代码
【发布时间】:2012-11-10 09:15:07
【问题描述】:

我正在玩一些 C# Winforms/WPF 代码,但偶然发现了一些奇怪的东西。 假设我有这样的代码:

public partial class MainWindow : Window
{
    public MainWindow()
    {
        InitializeComponent();
        DoSomething();

        // maybe something more if everything went ok
    }
}

令我困惑的是,在构造函数完成其工作之前,我不能简单地从方法 DoSomething 关闭应用程序。如果在执行DoSomething 期间发生任何事情失败,我需要立即关闭应用程序,但它只是继续运行,执行部分// maybe something more... 然后关闭,但这对我来说太晚了。

我必须将用于关闭表单的代码放入构造函数本身,并使用下面的return;,然后它才能工作,但我并没有真正找到一个可以接受的解决方案。我正在尝试将此类验证逻辑从构造函数移到我的方法中。

我尝试过类似的东西

public void DoSomething()
{
    Close();
}

public void DoSomething()
{
    Application.Current.Shutdown();
}

但它似乎不起作用。是的,这两个代码都会关闭应用程序,但只有在完全完成的构造函数代码之后。

Why 我需要这样的东西吗?好吧,因为在启动时我需要检查各种东西,比如连接和硬件的可用性,验证用户等,如果有任何失败,执行更多代码也没有意义。

用 Winforms 和 WPF 尝试了相同的原理(因此有标签),效果相同。

谁能提供解释或解决方案?

【问题讨论】:

  • 创建第一个表单时,没有应用程序正在运行,因此可能会忽略 Shutdown()。 Avip 提供了很好的解决方案。

标签: c# wpf winforms


【解决方案1】:

在您的情况下尝试使用Environment.Exit(-1),一切都会好起来的。

已添加: 这是我能为您提供的最佳参考。

Application.Exit vs Application.Shutdown vs Environment.Exit之间的区别

Application.Exit() 用于以优雅的方式退出 Windows 窗体应用程序。基本上,它会在调用 Application.Run() 之后停止消息泵、关闭所有窗口并让您回到 Main() 方法。但是,有时它似乎不起作用 - 这通常是因为还有其他前台线程(除了 UI 线程)仍在运行,这会阻止线程结束。

Application.Shutdown()(大体上)相当于 WPF 应用程序中的 Application.Exit()。但是,您有更多的控制权,因为您可以设置 ShutDownMode 以便应用程序在主窗口关闭、最后一个窗口关闭或仅在调用此方法时关闭。

Environment.Exit() 杀死所有正在运行的线程并且进程本身死了。这应该仅在更优雅的方法由于某种原因不起作用时作为最后的手段在 WF 或 WPF 中使用。它还可用于从控制台应用程序中突然退出。

另一个参考:How to properly exit a C# application?

【讨论】:

  • 谢谢,这似乎符合预期。你能解释一下,为什么它不适用于Shutdown()Close()?您的解决方案是否存在任何陷阱?
  • 没有陷阱。相反,Environment.Exit 的核心职责是终止进程并为底层操作系统提供指定的退出代码。参考:msdn.microsoft.com/en-us/library/system.environment.exit.aspx
  • 谢谢。有时我不需要抛出异常等,只是一个简单的“退出”。 :)
  • 不错。 +1 以获得清晰且全面分级的备选方案列表。
【解决方案2】:

你总是可以忽略你的开发者伙伴,直接使用Environment.FailFast()

但真的 - 不要。如果您有关键的事情要做,S.A 验证串行端口是否连接到核电站,请提前完成。没有规则会在调用Main() 后立即强制您使用Application.Run(...)

【讨论】:

  • 您能否详细说明一下,为什么不这样做? FSX 的解决方案似乎有效,他的方法是否有任何潜在的问题需要注意? Application.Run 仅与 Winforms 相关(或者我错了?),但是 WPF 呢?请您在 WPF 中展示一个示例来说明您的解决方案,例如你会把关键的引导指令放在哪里(检查打开的端口和类似的东西)?简单的例子就可以了。
【解决方案3】:

已经发布了针对您的问题的可行解决方案。

只是为了回答您的后续问题:Close() 和 Shutdown() 等方法不会立即退出您的应用程序的原因是它们都只是将消息推送到应用程序的消息队列中。它们仅在 MainWindow 的构造函数完成并且代码执行返回到消息处理循环后才被处理,甚至可能在队列中其他一些仍待处理的消息也已被处理之后。 相反,Environment.Exit() 或 Environment.FailFast() 之类的方法是一种硬核 os 函数,或多或少会导致进程立即终止。

【讨论】:

  • 感谢您的解释。可惜我不能选择多个答案。至少也为你 +1 :)
【解决方案4】:

解决方法是抛出异常并在application.UnhandledException 中处理它

【讨论】:

    【解决方案5】:

    定义一个异常类:

    public class InitializationException : Exception
    {
        public InitializationException()
        {}
    
        public InitializationException(string msg)
            : base(msg)
        {}
    
        public InitializationException(string msg, Exception inner)
            : base(msg, inner)
        {}
    }
    

    并像这样更改您的代码:

    public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();
            try
            {
                DoSomething();
    
                // maybe something more if everything went ok
            }
            catch( InitializationException ex )
            {
                // log the exception
                Close();
            }
        }
    
        public void DoSomething()
        {
            if (notSomethingOK)
                throw new InitializationException( "Something is not OK and the applicaiton must shutdown." );
        }
    }
    

    这是一个干净且可维护的解决方案。

    【讨论】:

      【解决方案6】:
      System.Windows.Forms.Application.Exit();
      

      【讨论】:

        【解决方案7】:

        从概念上讲,此类东西不应在类构造函数中使用。构造函数在某种程度上是用于初始化具有起始状态的实例,而不是实际可能发生的事情(如异常、消息框等)。

        不要忘记,如果你需要中断它的执行,你可以从构造函数中return;。这是更好的策略(大多数情况下,您不需要在出现错误时关闭应用程序而不显示一些文本)。

        在 Windows/WPF 上的 C# 中有“显示窗口”、“可见性改变”、“加载”和许多其他事件,您可以虚拟覆盖或添加为事件处理程序。在那里初始化您的表单/应用程序。

        它们是正常的方法,所以一切都按预期工作。您可以尝试抛出您的应用程序入口点(主函数)将捕获并忽略的异常。

        对于 WPF,请检查: - https://msdn.microsoft.com/en-us/library/system.windows.forms.application.setunhandledexceptionmode(v=vs.110).aspx.

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2014-02-22
          • 1970-01-01
          • 2021-03-12
          相关资源
          最近更新 更多