I've got a thread that goes out and looks up data on our (old) SQL server.
As data comes in, I post information to a modal dialog box - the user can't & shouldn't do anything else while all this processing is going on. The modal dialog box is just to let them see that I'm doing something and to prevent them from running another query at the same time.
Sometimes (rarely) when the code makes a call to the SQL server, the server does not respond (IT has it down for maintenance, the LAN line got cut, or the PC isn't on the network) or the person doing the query runs out of time. So, the modal dialog box does have a cancel button.
The Thread object (System.Threading.Thread) has IsBackground=true
.
When someone clicks Cancel, I call my KillThread
method.
Note: I can NOT use the BackgroundWorker component in this class because it is shared with some Windows Mobile 5 code & WM5 does not have the BackgroundWorker.
void KillThread(Thread th) {
if (th != null) {
ManualResetEvent mre = new ManualResetEvent(false);
Thread thread1 = new Thread(
() =>
{
try {
if (th.IsAlive) {
//th.Stop();
// 'System.Threading.Thread' does not contain a definition for 'Stop'
// and no extension method 'Stop' accepting a first argument of type
// 'System.Threading.Thread' could be found (are you missing a using
// directive or an assembly reference?)
th.Abort();
}
} catch (Exception err) {
Console.WriteLine(err);
} finally {
mre.Set();
}
}
);
string text = "Thread Killer";
thread1.IsBackground = true;
thread1.Name = text;
thread1.Start();
bool worked = mre.WaitOne(1000);
if (!worked) {
Console.WriteLine(text + " Failed");
}
th = null;
}
}
In my Output Window, I always see "Thread Killer Failed" but no exception is ever thrown.
How should I stop a thread?
The best related posts I found where the two below:
How to Kill Thread in C#?
How to kill a thread instantly in C#?
EDIT:
There seems to be some confusion with the method I listed above.
First, when someone clicks the cancel button, this routine is called:
void Cancel_Click(object sender, EventArgs e) {
KillThread(myThread);
}
Next, when I go in to kill a thread, I'd rather not have to wait forever for the thread to stop. At the same time, I don't want to let my code proceed if the thread is still active. So, I use a ManualResetEvent
object. It should not take a full second (1000ms) just to stop a thread, but every time the WaitOne
method times out.
Still listening for ideas.
Excessive Refrigerant Charge Either way, an overcharged system may end up destroying your compressor through the phenomenon known as liquid slugging. Liquid slugging refers to the penetration of liquid refrigerant into moving parts of the compressor where only gaseous refrigerant was meant to go.
Outdoor AC compressors lose airflow and thus, energy efficiency when leaves, dirt, dust, and other debris collect on it. This is because the clogged air conditioner vents can't circulate air efficiently. This, similar to a dirty air filter, causes the unit to work harder to produce the same cooling results.
Material. You can use bleach as an excellent choice to clean a window air conditioner since it destroys mold. Unfortunately, it will also destroy metal and some parts of your AC.
Short Answer: You don't. Normally you do it by signaling you want to quit. If you're firing an SQL query, do it asynchronously (pardon my spelling), and cancel it if necessary. That really goes for any lengthy task in a separate thread.
For further reading see Eric Lippert's articles: Careful with that axe, part one: Should I specify a timeout? and Careful with that axe, part two: What about exceptions?
Edit: How do you call SQL Server? ADO, TDS, Standard/Custom Library, etc... ? THAT call should be made asynchrone. Thus: StartOpeningConnection, WaitFor OpeningComplete, StartQuery, WaitFor QueryComplete, Start CloseConnection, WaitFor CloseConnectionComplete etc. During any of the waits your thread should sleep. After waking up, Check if your parent thread (the UI thread) has cancelled, or a timeout has occurred and exit the thread and possibly inform sqlserver that you're done (closing connection).
It's not easy, but it rarely is...
Edit 2:In your case, if you are unable to change the database code to asynchrone, make it a seperate process and kill that if neccesary. That way the resources (connection etc.) will be released. With threads, this won't be the case. But it's an ugly hack.
Edit 3: You should use the BeginExecuteReader/EndExecuteReader Pattern. this article is a good reference: It will require rewriting your data access code, but it's the way to do it properly.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With