wpf 停止执行 C# 代码

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/13320758/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-13 06:08:11  来源:igfitidea点击:

Stop executing C# code

c#wpfwinforms

提问by walther

I'm playing a little bit with some C# Winforms/WPF code and just stumbled upon something strange. Let's say I have a code like this:

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

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

        // maybe something more if everything went ok
    }
}

What puzzles me is that I cannot simply close the application from the method DoSomething before the constructor finishes its job. If anything during the execution of DoSomethingfails, I need to close the application immediately, but it just keeps running, executes the part // maybe something more...and THEN closes, but that's way too late for me.

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

I have to put the code for closing the form inside the constructor itself with a following return;and then it works, but I don't really find that an acceptable solution. I'm trying to move such validation logic from the constructor to my methods.

我必须将关闭表单的代码放在构造函数本身中,return;然后它可以工作,但我真的没有找到一个可以接受的解决方案。我试图将这种验证逻辑从构造函数移到我的方法中。

I tried things like

我试过这样的事情

public void DoSomething()
{
    Close();
}

or

或者

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

But it doesn't seem to work. Yes, both codes do close the application, but only after a fully finished constructor code.

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

Whywould I need such a thing? Well, because at startup I need to check for various things, like availability of the connection and hardware, validate the user etc, and if anything fails, there's no point of executing more code.

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

Tried the same principle with Winforms and WPF (hence the tags), works the same.

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

Can anybody provide an explanation or maybe a solution?

任何人都可以提供解释或解决方案吗?

回答by Furqan Safdar

Just try using Environment.Exit(-1)in your situation and all will be good.

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

ADDED:This is the best reference i can get for you.

补充:这是我能为你得到的最好的参考。

Difference between Application.Exitvs Application.Shutdownvs Environment.Exit

vs vs之间的区别Application.ExitApplication.ShutdownEnvironment.Exit

Application.Exit()is for exiting a windows forms application in a graceful way. Basically, it stops the message pump, closes all windows and lands you back in the Main() method just after the call to Application.Run(). However, sometimes it doesn't appear to work - this is usually because there are other foreground threads (apart from the UI thread) still running which are preventing the thread from ending.

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

Application.Shutdown()is (broadly) the equivalent of Application.Exit() in a WPF application. However, you have a bit more control as you can set the ShutDownMode so that the application shuts down when the main window closes, the last window closes or only when this method is called.

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

Environment.Exit()kills all running threads and the process itself stone dead. This should only be used in WF or WPF as a last resort when the more graceful methods are not working for some reason. It can also be used to make an abrupt exit from a console application.

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

Another Reference: How to properly exit a C# application?

另一个参考:如何正确退出 C# 应用程序?

回答by avishayp

You can always ignore your fellow developers and just use Environment.FailFast()

你总是可以忽略你的开发人员,只使用Environment.FailFast()

But really - don't. If you have critical things to do, S.A verifying the serial port is connected to the nuclear power plant, just do it prior. There's no rule forcing you to Application.Run(...)as soon as Main()is called.

但真的 - 不要。如果你有关键的事情要做,SA验证串口是否连接到核电站,先做。没有任何规则强迫您在被召唤时Application.Run(...)立即这样做Main()

回答by markus987

There have already been posted viable solutions for your problem.

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

Just to answer your follow-up question: the reason why methods like Close() and Shutdown() do not immediately exit your application is that both just push messages into the application's message queue. They are only processed after MainWindow's constructor finished and code execution returns to the message processing loop, maybe even after some other still pending messages in the queue have been handled too. On the contrary, methods like Environment.Exit() or Environment.FailFast() are kind of hard-core os functions leading to more or less immediately killing the process.

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

回答by Eranga Gamagedara

System.Windows.Forms.Application.Exit();

回答by Croll

Conceptually such things should not be used in class constructors. Constructor is somewhat made for instance initialization with starting state and not the actual things may happen (like exceptions, message boxes, etc).

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

Don't forget that you can just return;from constructor, if you need to break its execution. This is better tactic (most times you don't need to just shutdown application on error without displaying some text).

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

There are "window shown", "visibility changed", "loaded" and many other events in C# on Windows/WPF, that you can override virtually or add as an event handler. Initialize your form/app there.

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

They're normal methods so all works as expected. You can try throwing exceptions that your application entry point (Main function) will just catch and ignore.

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

For WPF, check this: - https://msdn.microsoft.com/en-us/library/system.windows.forms.application.setunhandledexceptionmode(v=vs.110).aspx.

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

回答by DjSol

A workaround would be to throw a exception and handle it in application.UnhandledException

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

回答by Mohammad Dehghan

Define an Exception class:

定义一个异常类:

public class InitializationException : Exception
{
    public InitializationException()
    {}

    public InitializationException(string msg)
        : base(msg)
    {}

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

and change your code like this:

并像这样更改您的代码:

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." );
    }
}

This is a clean and maintainable solution.

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