C# 显示对话框时出现“线程被中止”异常

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/220643/
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-08-03 18:41:56  来源:igfitidea点击:

"Thread was being aborted" exception whilst displaying dialog

c#.netmultithreading.net-2.0

提问by MoreThanChaos

In my app I've got a thread which displays for some time "please wait" dialog window, sometimes it is a very tiny amout of time and there is some glitch while drawing UI (I guess).

在我的应用程序中,我有一个线程会显示一段时间“请等待”对话框窗口,有时它的时间非常短,并且在绘制 UI 时会出现一些故障(我猜)。

I get the exception "Thread was being aborted" and completly have no idea how get rid of it. I mean Catch that exception in some way, or in some other way hide it from user. This exception has got nothing to do with rest of my app and that error in any way doesn't affect it. Appears randomly and it is hard to recreate on a call.

我收到异常“线程正在中止”并且完全不知道如何摆脱它。我的意思是以某种方式捕获该异常,或者以某种其他方式将其隐藏起来。此异常与我的应用程序的其余部分无关,并且该错误不会以任何方式影响它。随机出现,很难在通话中重新创建。

I tried in various ways to catch that exception by side of code which starts and stops thread with dialog window but it seems that error apparently is by side some other thread which dispalys window in my newly created thread.

我尝试以各种方式在代码旁边捕获该异常,该代码通过对话框窗口启动和停止线程,但似乎该错误显然是在我新创建的线程中显示窗口的其他线程旁边。

Here is a code sample, part of static class with useful stuff, of course I don't say that is good way to solve this kind of "busy" situation but I want to solve this problem. Thread.Sleep(500); or other try/catch improvments doesn't help me to avoid that thread exception.

这是一个代码示例,静态类的一部分,有一些有用的东西,当然我不是说这是解决这种“忙碌”情况的好方法,但我想解决这个问题。线程.睡眠(500); 或其他 try/catch 改进并不能帮助我避免该线程异常。

    public static bool alreadyBusy = false;
    public static BusyIndicator bi = new BusyIndicator("");
    public static Thread backgroundOpertionThread;

    public static void showBusy(bool isBusy, System.Windows.Forms.Form hostform, string message)
    {
        Common.busyMessage = message;
        if (isBusy)
        {
            Common.alreadyBusy = true;
            backgroundOpertionThread = new Thread(new ThreadStart(showBusy));
            Thread.Sleep(500);
            if (hostform != null)
            {
                hostform.Enabled = false;
                hostform.SuspendLayout();
            }
            backgroundOpertionThread.Start();

        }
        else
        {

            backgroundOpertionThread.Abort();
            Thread.Sleep(500);
            Common.alreadyBusy = false;
            if (hostform != null)
            {
                hostform.Enabled = true;
                hostform.ResumeLayout();
            }
        }
    }

    public static void showBusy()
    {
        BusyIndicator bir = new BusyIndicator(Common.busyMessage);
        bir.ShowDialog();
    }

Any ideas?

有任何想法吗?

采纳答案by Lasse V. Karlsen

Do notuse Thread.Abort. This method is reserved for when the .NET runtime needs to forcibly kill threads in order to unload your program.

千万不能使用Thread.Abort的。此方法保留用于 .NET 运行时需要强制终止线程以卸载程序的情况。

You can only "safely" use this if you're about to unload an AppDomain and want to get rid of threads running in it first.

如果您要卸载 AppDomain 并希望首先摆脱其中运行的线程,则只能“安全地”使用它。

To get rid of a thread, write it in cooperative mode. This means that the thread should periodically check some kind of flag, and if the flag is set, exit normally out of the thread method. To "kill" the thread, simply set the flag and wait for the thread to exit.

要摆脱线程,请以协作模式编写它。这意味着线程应该定期检查某种标志,如果设置了标志,则正常退出线程方法。要“杀死”线程,只需设置标志并等待线程退出。

You can use an Event-object or a simple boolean variable for this flag.

您可以为此标志使用事件对象或简单的布尔变量。

But do not use Thread.Abort.

不要使用 Thread.Abort

回答by Steven A. Lowe

use SafeThreadand set ShouldReportThreadAbort to false to make the problem go away...

使用SafeThread并将ShouldReportThreadAbort设置为 false 以使问题消失......

a better solution would be to run this in the debugger with Debug >> Exceptions >> Thrown checked for all exception types, and figure out what is happening to abort your thread

更好的解决方案是在调试器中运行它并使用 Debug >> Exceptions >> Throw 检查所有异常类型,并找出中止线程的情况

EDIT: thanks for posting the code sample, that makes the problem much easier to see. DO NOT CALL THREAD.ABORT

编辑:感谢您发布代码示例,这使问题更容易看到。不要调用线程中止

回答by joshua.ewer

Agreed with Steven's idea about turning on all exceptions when thrown. Then you'll be able to immediately see the problem.

同意 Steven 关于在抛出时打开所有异常的想法。然后,您将能够立即看到问题。

One thing that's important to remember, you won't have the debug menu option if your visual studio settings are on general, as opposed to the "Visual C# Developer" setting. Still catches me if I'm on a new machine or using a new profile...

需要记住的一件事是,如果您的 Visual Studio 设置为常规设置,则您将没有调试菜单选项,而不是“Visual C# Developer”设置。如果我在新机器上或使用新配置文件,仍然会抓住我...

回答by Veldmuis

You can try calling

你可以试试打电话

Thread.Sleep(500);

after

backgroundOpertionThread.Start();

This would give the background thread 500 ms to do what it needs to do before the main thread gets an opportunity to call

这将使后台线程有 500 毫秒的时间在主线程有机会调用之前做它需要做的事情

backgroundOpertionThread.Abort();

Edit: But I agree that the best solution would be not to use Thread.Abort() at all

编辑:但我同意最好的解决方案是根本不使用 Thread.Abort()