Solved

C#: Error: Thead is not running; it cannot be resumed. What???

Posted on 2004-10-01
18
549 Views
Last Modified: 2010-08-05
  Well something is running because Windows 2000 Server Task Manager says so. I use the code below to start two threads within a windows app. Now I would like to Suspend and then Resume one thread and I receive the following error.

   ERROR: Thead is not running; it cannot be resumed!

private void Form1_Load(object sender, System.EventArgs e)
{
Class2 obj_class2 = new Class2();
Class3 obj_class3 = new Class3();
      
Thread[] threads = new Thread[2];
threads[0] = new Thread(new ThreadStart(obj_class2.StartNow));  // StartNow is a Public method in Class2.cs
threads[1] = new Thread(new ThreadStart(obj_class3,StartHere)); // StartHere is a Public method in Class3.cs

threads[0].Start();
threads[1].Start();
}

So, I use the following code latter on the same Windows Form1 to attempt to Suspend threads[1]............

private void UpdateSqlTablesNow()  // Need to update SQL tables and Suspend threads[1] to do so.........
{
//Class2 obj_class2 = new Class2();
Class3 obj_class3 = new Class3();  // <--------------- New Instance of Class3 for object
      
Thread[] threads = new Thread[2];
threads[0] = new Thread(new ThreadStart(obj_class2.StartNow));  // StartNow is a Public method in Class2.cs
threads[1] = new Thread(new ThreadStart(obj_class3,StartHere)); // StartHere is a Public method in Class3.cs

//threads[0].Start();
if ((threads[1] != null) && (threads[1].IsAlive)) { threads[1].Suspend(); } // <---------------- Now Suspending thread[1]-------------

// SQL table update code here/////////////////////////

threads[1].Resume(); // <---------------- Now Resuming thread[1]------------- ERROR: Thead is not running; it cannot be resumed!




0
Comment
Question by:kvnsdr
  • 6
  • 6
  • 4
  • +1
18 Comments
 
LVL 14

Expert Comment

by:AvonWyss
ID: 12204514
Could it be that the thread in question was already done with it's work when you suspended it?
0
 
LVL 1

Author Comment

by:kvnsdr
ID: 12205150
Well, that's a good question. I posted question below concerning monitoring thread performance for development reasons. I haven't found any app yet that can track these procedures. I know the thread in question is working however, I don't know if threads behave in an on-off mannor during normal operation. I know everytime I run the app I get the same error. Help............

http://www.experts-exchange.com/Programming/Programming_Languages/C_Sharp/Q_21146425.html
0
 
LVL 19

Expert Comment

by:drichards
ID: 12205184
What do your thread procs look like?  Can they exit of their own accord or do they wait for you to kiil them?

Ralated to both this question and your other one, you should think about adding explicit thread synchronization.  It's a bad idea in general to just suspend/kill threads from other threads since you don't know what state the thread is in when it stops.  Explicit synchronization will ensure that things are in a known state at all times and avoid issues like the one you are experiencing.
0
 
LVL 3

Expert Comment

by:a_goat
ID: 12212304
I might have missed something, but in the second bit of code, where do you start threads[1]?

It looks like you're recreating the threads array, which creates 2 completely new threads (so at this point you've created a total of 4 - 2 in the constructor, 2 in UpdateSqlTablesNow).  Then you suspend one of the new threads (which isn't running yet), run your SQL, and then try to resume the thread.

0
 
LVL 1

Author Comment

by:kvnsdr
ID: 12213065
1. To answer your question concerning restarting the thread array, I kept receiving an error 'no instance of a thread to suspend', so it seemed the only way to elimnate the error. It worked however it may technically be incorrect methodology......

2. I had a problem with threads[1] dying after approx. 2.5 minutes. So I devised a timer to trip 'StartThreads' method to reasure the thread is running.

   Q. With my new method, am I recreating new threads every 2.5 minutes???
       (BTW, I now recieve an 'thread pool' error approx every 1 hour. As soon as I clear it, all is fine. help...)


private void Form1_Load(object sender, System.EventArgs e)
{
StartThreads();
}

private void StartTheads()
{
Class2 obj_class2 = new Class2();
Class3 obj_class3 = new Class3();
     
Thread[] threads = new Thread[2];
threads[0] = new Thread(new ThreadStart(obj_class2.StartNow));  // StartNow is a Public method in Class2.cs
threads[1] = new Thread(new ThreadStart(obj_class3,StartHere)); // StartHere is a Public method in Class3.cs
if((threads[0] != null) && (threads[0].IsAlive)) { } else { threads[0].Start();       }
if((threads[1] != null) && (threads[1].IsAlive)) { } else { threads[1].Start();       }
}

private void UpdateSqlTablesNow()  // Need to update SQL tables and Suspend threads[1] to do so.........
{
// SQL table update code here/////////////////////////

StartThreads();
}
0
 
LVL 19

Assisted Solution

by:drichards
drichards earned 250 total points
ID: 12213200
You'd be better off putting some effort into figuring out why you have a thread dying rather than trying to figure out odd ways to handle its disappearance.  You will just end up making your code unnecessarily complicated.  What is the thread function and do you have an idea why it is dying after some time?
0
 
LVL 3

Expert Comment

by:a_goat
ID: 12213360
Here's what I would do.  This is the safest approach:

class Class2
{
public void StartNow()
{
while (NotFinishedWorking)
{
lock(this)
{
// Do a work unit
}
}
}
}

class Class3
{
public void StartHere()
{
while (NotFinishedWorking)
{
lock(this)
{
// Do a work unit
}
}
}
}

Class2 obj_class2 = new Class2();
Class3 obj_class3 = new Class3();

private void Form1_Load(object sender, System.EventArgs e)
{
Thread[] threads = new Thread[2];
threads[0] = new Thread(new ThreadStart(obj_class2.StartNow));  // StartNow is a Public method in Class2.cs
threads[1] = new Thread(new ThreadStart(obj_class3,StartHere)); // StartHere is a Public method in Class3.cs

foreach (Thread t in threads)
t.Start();
}

private void UpdateSqlTablesNow()
{
lock(obj_class2)
lock(obj_class3)
{
// Update the SQL tables
}
}


What this approach does is the safest.  It ensures that the threads can't be using the database while you're updating them.  The threads themselves handle pausing and resuming due to the lock statements.  You don't have to worry about suspending and resuming them yourself.
0
 
LVL 1

Author Comment

by:kvnsdr
ID: 12213749
What is (NotFinishedWorking)?
0
 
LVL 19

Expert Comment

by:drichards
ID: 12213776
a_goat,

I'm not sure what synchronization object you're proposing as 'lock(object)' is evidently a user-defined construct, but the concept is good.  That is the explicit synchronization I was proposing earlier.  Depending on the implementation, you could use a Mutex or Monitor to control access to the database code.

This will still leave the problem of crashing/exiting threads, however, and that will need to be solved as well.
0
Find Ransomware Secrets With All-Source Analysis

Ransomware has become a major concern for organizations; its prevalence has grown due to past successes achieved by threat actors. While each ransomware variant is different, we’ve seen some common tactics and trends used among the authors of the malware.

 
LVL 19

Expert Comment

by:drichards
ID: 12213790
'NotFinishedWorking' is a flag that in the example code snippet tells the thread function to keep executing.  The example is executing a while loop until the flag is unset at which point the thread function will exit.  Your actual thread function may or may not have something like that.
0
 
LVL 3

Expert Comment

by:a_goat
ID: 12213819
Ummmmm, lock() is not a user defined construct at all.  Check your C# language reference again: http://msdn.microsoft.com/library/default.asp?url=/library/en-us/csref/html/vclrflockstatement.asp

lock(foo)
{
// stuff
}

is functionally identical to

try
{
Monitor.Enter(foo);
// stuff
}
finally
{
Monitor.Exit(foo);
}
0
 
LVL 19

Expert Comment

by:drichards
ID: 12213828
Hey, well what do you know.  And here I've been coding explicit Monitor calls all this time.

Then yes, that's exactly it.
0
 
LVL 19

Expert Comment

by:drichards
ID: 12213853
Assuming, of course, that the database code is in these objects.  Not much to go on from the code shown so far and the database code seems to be in a Form1 method from what I see - Form1_Load, StartThreads, and UpdateSqlTablesNow all seem to be Form1 methods, so there is evidently databsae code in both Form1 and Class2 and Class3, which says a Mutex may be required or code needs to be moved.
0
 
LVL 1

Author Comment

by:kvnsdr
ID: 12214186
2. I had a problem with threads[1] dying after approx. 2.5 minutes. So I devised a timer to trip 'StartThreads' method to reasure the thread is running.

   Q. With my new method, am I recreating new threads every 2.5 minutes???
       (BTW, I now recieve an 'thread pool' error approx every 1 hour. As soon as I clear it, all is fine. help...)


private void Form1_Load(object sender, System.EventArgs e)
{
StartThreads();
}

private void StartTheads()
{
Class2 obj_class2 = new Class2();
Class3 obj_class3 = new Class3();
     
Thread[] threads = new Thread[2];
threads[0] = new Thread(new ThreadStart(obj_class2.StartNow));  // StartNow is a Public method in Class2.cs
threads[1] = new Thread(new ThreadStart(obj_class3,StartHere)); // StartHere is a Public method in Class3.cs
if((threads[0] != null) && (threads[0].IsAlive)) { } else { threads[0].Start();      }
if((threads[1] != null) && (threads[1].IsAlive)) { } else { threads[1].Start();      }
}

private void UpdateSqlTablesNow()  // Need to update SQL tables and Suspend threads[1] to do so.........
{
// SQL table update code here/////////////////////////

StartThreads();
}
0
 
LVL 3

Accepted Solution

by:
a_goat earned 250 total points
ID: 12214730
If you do that, you will be creating a lot of useless threads.  Like someone said, you need to check into why those threads are dying.  Put the whole routine into a try/catch block to see if an exception is being thrown, or some other weirdness.

If you want to monitor the number of threads your app creates, there are two things to do.  First, in the task manager, bring up the process list and go to View > Select Columns.  You can add a Thread Count column to watch how many threads get created (keep in mind, an extra 3 or 4 are added by .NET, but you'll get a rough idea)

Second, Visual Studio has a toolbar to show you processes it's attached to and threads.  I can't remember which toolbar it is and I don't have it in front of me.  When you pause execution or hit a breakpoint, you can switch between threads and see what they're doing.

Finally, you can make Visual Studio break on any exception.  I think it's under Debugging > Exceptions.  This may help you in finding out if an exception is being thrown unexpectedly.
0
 
LVL 14

Expert Comment

by:AvonWyss
ID: 12215152
Why don't you make your Class2 and Class3 classes to be thread wrappers? I mean put the thread code inside them. This would give you better separation of the thread code and app code and it would also prevent those mysterious thread problems.

public class Class2 {
    private Thread thread;
    private bool terminate;
   
    public Class2() {
        thread=new Thread(new ThreadStart(DoWork));
        thread.Start();
    }

    private void DoWork() {
        while (!terminate) {
            lock (this) {
                // do your work here
            }
        }
    }

    public void Terminate() {
        terminate=true;
        thread.Join();
    }
}
0
 
LVL 1

Author Comment

by:kvnsdr
ID: 12217540
I will use the 'Task Manager' to monitor the running app and let you know...........
0
 
LVL 1

Author Comment

by:kvnsdr
ID: 12251621
Thank you drichards:
 "You'd be better off putting some effort into figuring out why you have a thread dying rather than..."

Thank you a_goat"
 "First, in the task manager, bring up the process list and go to View > Select Columns.  You can add a Thread Count column to watch how many threads get created (keep in mind, an extra 3 or 4 are added by .NET, but you'll get a rough idea)..."
0

Featured Post

What Security Threats Are You Missing?

Enhance your security with threat intelligence from the web. Get trending threat insights on hackers, exploits, and suspicious IP addresses delivered to your inbox with our free Cyber Daily.

Join & Write a Comment

Suggested Solutions

Article by: Ivo
C# And Nullable Types Since 2.0 C# has Nullable(T) Generic Structure. The idea behind is to allow value type objects to have null values just like reference types have. This concerns scenarios where not all data sources have values (like a databa…
This article describes a simple method to resize a control at runtime.  It includes ready-to-use source code and a complete sample demonstration application.  We'll also talk about C# Extension Methods. Introduction In one of my applications…
Illustrator's Shape Builder tool will let you combine shapes visually and interactively. This video shows the Mac version, but the tool works the same way in Windows. To follow along with this video, you can draw your own shapes or download the file…
Polish reports in Access so they look terrific. Take yourself to another level. Equations, Back Color, Alternate Back Color. Write easy VBA Code. Tighten space to use less pages. Launch report from a menu, considering criteria only when it is filled…

758 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

21 Experts available now in Live!

Get 1:1 Help Now