FerasGer83

i have two questions about threading.

1- if we run this program:

Code Snippet

static void Main(string[] args)

{

Thread t = new Thread(new ThreadStart(doSomething));

t.Start();

t.Abort();

Console.ReadLine();

}

static void doSomething()

{

for (int i = 0; i < 1000; i++)

Console.WriteLine(i.ToString());

}

when i ran this program without debugging ( ctrl + F5 ), the thread prints some values before it's been terminated.

but when i ran it using debugging mode ( F5 ), the thread never prints any value, as it's been terminated without having the chance to get the CPU.

so why there is such difference in these two modes

2- if we changed the code to be right this:

Code Snippet

static void Main(string[] args)

{

Thread t = new Thread(new ThreadStart(doSomething));

t.Start();

t.Abort();

Console.ReadLine();

}

static void doSomething()

{

Thread.BeginCriticalRegion();

for (int i = 0; i < 1000; i++)

Console.WriteLine(i.ToString());

Thread.EndCriticalRegion();

}

the thread is supposed to complete it's work because it's all in the CriticalRegion, but the thread is being terminated and it never completes it's work.



Re: Visual C# General a problem in aborting threads

Peter Ritchie

With code like:

Code Snippet

thread.Start();

thread.Abort();

...you're in-deterministically terminating your thread. This may occur before the thread starts running or after the thread starts running. It also means it could abort the thread before the critical region is created or after/during.

As far as I know, BeginCrticicalRegion and EndCriticalRegion only do anything when running managed code in SQL Server.






Re: Visual C# General a problem in aborting threads

tlehr

2nd example)

Thread.BeginCriticalRegion does nothing more than increment a counter. It does not guarantee thread execution, its just a way to notify the host(ie: SQL Host) that the appdomain needs to be reloaded since its state is corrupted.





Re: Visual C# General a problem in aborting threads

Steve Py

I find it easier to code around a model where the worker threads respond to a Mutex or volatile flag as an indication that they should stop what they're doing and prepare to be re-joined into the main thread. Should they be in a completely unresponsive state, I'll use an Interrupt to break them out before shutting down the application.

The difference you see between debugging and non-debugging is simply that debugging mode is "slower" in that the code in your main thread has given enough time for the worker thread to start up and get going. Without the debugging details it's aborting the worker before the worker has even done anything.

Here's a pretty simple example. doSomething doesn't really have the possibility to get into an unresponsive state, however if it had started processing something (like parsing through a particularly large text file) that took longer than 5 seconds before it checked its abort flag, the main thread would trigger an interrupt. That breaks the worker thread using an exception. The benefit of an interrupt rather than an abort is that you can record the interrupt occurance in a trace log etc. so that as you test your applications you can tune them to avoid situations where you're "violently" terminating threads. This example can be improved by using WaitHandles or Mutex'es to signal state between the threads. Volatile variables are crude, but they do the job. Wink

private volatile bool _abortWorker = false;

static void Main()

{

Thread t = new Thread( new ThreadStart( doSomething ) );

t.Start();

Thread.Sleep(500);

_abortWorker = true;

if (!t.Join( new Timespan( 0, 0, 5) ) )

{

t.Interrupt();

}

}

private static void doSomething()

{

try

{

for ( int i = 0; i < 1000; i++ )

{

Console.WriteLine( i.ToString() );

if ( _abortWorker )

break;

}

}

catch ( ThreadInterruptException )

{

Console.WriteLine( "Worker thread was unresponsive. Interrupted." );

}

}






Re: Visual C# General a problem in aborting threads

OmegaMan

If you must terminate a thread, have the thread handle the ThreadAbort exception which is thrown by the OS and gracefully shut down. I have example code on my blog entitled How to handle a .Net 2/3 Abort Exception in Threading.





Re: Visual C# General a problem in aborting threads

Peter Ritchie

Handling the ThreadAbort exception is problematic (e.g. if the thread is within another catch block it won't be aborted until it exits the catch block [see 1], and if the thread is in a catch block higher that the TheadAbortException catch [see 2] then it will be abnormally terminated.

I recommend cooperative termination and pausing of threads. See 'System.Threading.Thread.Suspend()' is obsolete: 'Thread.Suspend has been deprecated... for an example of a thread class that cooperatively terminates and suspends.

[1]

Code Snippet

try

{

try

{

// ...

}

catch (Exception)

{

// All the code in this block will always be executed.

}

}

catch (ThreadAbortException)

{

}

[2]

Code Snippet

try

{

// ...

}

catch (ThreadAbortException)

{

// TODO: something

}

catch (Exception)

{

// Code in this block could be aborted at any time

}