views:

2681

answers:

4

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).

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.

    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?

A: 

use SafeThread and set ShouldReportThreadAbort to false to make the problem go away...

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

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

Steven A. Lowe
The problem is that thus exeption is hard to recreate, especially in Debug Enviromnent due to bit slowdown on operations which debug enviroment provides.As far i remember stacktrace error lays in GUI drawing thread of NET Framework above my code
MoreThanChaos
and ofcourse i try to use your advices, but there will be no way to make accurate tests, cause as i said exeption factors are hard to recreate
MoreThanChaos
A: 

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...

joshua.ewer
already tryied on two diffrent machines, besides please read comments to previous answer
MoreThanChaos
+9  A: 

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.

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.

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.

Lasse V. Karlsen
+1. And just for emphasis: *Do not use Thread.Abort!* :-)
Lette
A: 

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

backgroundOpertionThread.Abort();

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

Veldmuis