views:

381

answers:

2

I am starting atmost 5 threads in a program in C# .NET. But sometimes some of those threads just quit or become dead inexplicably even before the completion of execution of the function assigned to it.

It happens randomly . If I try to debug the code by putting breakpoints- It works fine.

And sometimes all the threads execute the assigned functions perfectly.They do not share any resources among them.

            Thread[] td = new Thread[5];
            for (count = 4; count >= 0; --count)
            {
                ds[count] = dba.getData(ru[count]);
                td[count] = new Thread(delegate() {  runRule[count].performTask(ru[count], ds[count], count); });
                td[count].Name = "Thread " + count.ToString();
                td[count].Start();
                Thread.Sleep(50);
            }

If I remove the last line "Thread.Sleep(50)" only the first thread stared runs and rest of them just die.

can someone explain why the threads are becoming dead?

+1  A: 

If a thread reaches the end of its execution path it will automatically end. In your exmaple once the thread has finished whatever the performTask method is it will exit.

If you want a thread to hang around forever (for debugging purposes only as you don't want unused threads hanging around in a real application) you could add something like the below to the end of the method that the thread is running.

ManualResetEvent stayAlive = new ManualResetEvent(false);
stayAlive.WaitOne();
sipwiz
Thanks for ur reply,I don't want the threads to hang around forever, the prob here is that they are not completing their full execution path.They are just dying or quitting before executing all the code.
LoyalBanana
+3  A: 

I suspect they're not becoming dead - I suspect the problem is that you're not actually running the rules you think you are. When you use a method's local variables within an anonymous method, the variables themselves are captured. In this case, you're capturing the count local variable - and then changing it (as the loop counter decreases). By the time a thread created when count=4 starts running, count may be 3 - so it will be calling runRule[3].performTask(ru[3], ds[3], 3). In fact, count could change while the expressions are being evaluated which could cause a lot of fun.

The way to get round this is to have a different "local" variable for each iteration of the loop. It's easy to do:

Thread[] td = new Thread[5];
for (count = 4; count >= 0; --count)
{
    int copy = count;
    ds[count] = dba.getData(ru[count]);
    td[count] = new Thread(delegate() {  
        runRule[copy].performTask(ru[copy], ds[copy], copy); 
    });
    td[count].Name = "Thread " + count.ToString();
    td[count].Start();
    Thread.Sleep(50);
}

Now the only variables being captured in the delegate are copy and runRule/ru/ds - I'm assuming that the latter three don't change. A new "instance" of the copy variable is created each time you go round the loop, so changes won't interfere with each other.

See whether this helps - it's at least a potential cause for massive confusion, and may well be the problem.

Jon Skeet
ThankyouForUrReplyThe prob u mentioned's avoided usin Thread.Sleep(50).Cause when the main thread waits for 50 millisecs, threads are created before the next iteration.That's not the main prob here,I have 5 prgresbrs to show how much progress is made.The threads just quit after showing some progress
LoyalBanana