views:

618

answers:

7

Hi,

I've got a small app that searches for and stores the names of a large number of files at start-up. I'm splitting this search into several Thread objects that each search one directory, and push results back to the main thread.

When the app loads, I go through each thread and load it:

foreach(Thread t in m_threads)
{
    t.Start();
    whiel(!t.IsAlive){}
}

When I begin this app in the debugger, it loads and the threads quickly find all the files. However if I start outside the debugger it freezes. Attaching the debugger to the process I can see that IsAlive never returns true.

I'm new to C# threading so does anyone have any idea what's going wrong, or how I can more easily debug what's happening?

+1  A: 

You perhaps mean IsAlive() "never returns false".

Well, if so, that's because your threads continue to execute infinitely. May be the method you're calling in these threads has an infinite loop or something.

Frederick
+1  A: 

It may not be exactly related to why things are freezing, but your implementation is quite questionable. You enumerate over a collection of threads, start each one, but then block until the thread is finished? I think what you may have meant to do is start all threads, then block until all threads have finished. (Note: This is assuming you meant to write: "while(t.IsAlive) {}", since waiting for the thread to start makes even less sense.)

As for the freezing, we may need to see the rest of the code. Since you said you are new to C# threading, and looking at what you did above, I am assuming you are also new to threading, which means there could be many places that a problem can rise.

Spodi
+3  A: 

The thread may have finished processing before your check against IsAlive.

WHy are you waiting by checking the IsAlive flag anyway?

Why not, instead, fire up all the threads, then in another loop, call Join() to wait for the threads to finish? No need to check "IsAlive".

Even better, why not use the ThreadPool instead of firing up a stack of threads yourself?

OJ
Thanks, I'll look into ThreadPools.
tenpn
+1  A: 

It appears I mis-understood the code I cut-and-paste'd to create my threading code. I assumed the while(!t.isAlive){} line was blocking until the thread could properly start itself, and thought it was necessary administration.

I removed that line and the app launches fine out of the debugger. I join the threads later in the code, so that should be it.

Is there a "NEWB!" tag? :)

tenpn
A: 

I don't know what you are doing in your threads exactly, but I think that...

Multithreading + Application behaving differently with debugger attached = Race conditions

I am pretty sure that you got some synchronization issues.

DrJokepu
+1  A: 

With the code you provided above, It seems to me that you want to start the threads sequentially. If so why do you need many threads? 1 thread can do the job.

EDIT: (after your answer)

Ok. I see that you removed the questionable line.

Even so, in your case, I would consider to use only one thread for loading these file names because you are accessing only one IO resource (the disk). Each thread is competing for this resource. Have you tried to move 1 big file in windows and then move another big file while the first is still moving? The performance of your disk decreases. Because of this I would only create one thread for each different IO resource.

bruno conde
+1  A: 

I would recommend not to hold a collection of Threads, but use Threadstarts instead. If you join them later, theres no need to wait until the Thread is running, so you while-loop is unnecessary. Make sure, your Threads are marked as Background-Threads, so they are cleaned up automatically after execution.

I would do this like this: List threadStarters = new List();

foreach (ThreadStart ts in threadStarters)
{
    Thread t = new Thread(ts);
    t.IsBackground = true;
    t.Start();
}
BeowulfOF