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.
这是一个代码示例,静态类的一部分,有用的东西,当然我不是说这是解决这种“忙”情况的好方法,但我想解决这个问题。 Thread.sleep代码(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?
4 个解决方案
#1
15
Do not use 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.
您可以为此标志使用Event-object或简单的boolean变量。
But do not use Thread.Abort.
但是不要使用Thread.Abort。
#2
1
use SafeThread and 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 >> Thrown检查所有异常类型,并找出中止线程的情况
EDIT: thanks for posting the code sample, that makes the problem much easier to see. DO NOT CALL THREAD.ABORT
编辑:感谢发布代码示例,这使问题更容易看到。不要打电话给THREAD.ABORT
#3
0
Agreed with Steven's idea about turning on all exceptions when thrown. Then you'll be able to immediately see the problem.
同意史蒂文关于在抛出时打开所有异常的想法。然后你就能立即看到问题所在。
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”设置。如果我在新机器上或使用新的配置文件,仍会抓住我...
#4
-3
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()
#1
15
Do not use 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.
您可以为此标志使用Event-object或简单的boolean变量。
But do not use Thread.Abort.
但是不要使用Thread.Abort。
#2
1
use SafeThread and 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 >> Thrown检查所有异常类型,并找出中止线程的情况
EDIT: thanks for posting the code sample, that makes the problem much easier to see. DO NOT CALL THREAD.ABORT
编辑:感谢发布代码示例,这使问题更容易看到。不要打电话给THREAD.ABORT
#3
0
Agreed with Steven's idea about turning on all exceptions when thrown. Then you'll be able to immediately see the problem.
同意史蒂文关于在抛出时打开所有异常的想法。然后你就能立即看到问题所在。
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”设置。如果我在新机器上或使用新的配置文件,仍会抓住我...
#4
-3
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()