I have a large application with lots of functions. Sometimes, when you close the main form - it exits smoothly. Other times the form closes, but the program remains running. Which debugging tools does Visual Studio 2010 provide for identifying misbehaving threads?
foreach (Form form in Application. OpenForms) { form. Close(); } Application. Exit();
Short Answer: When a thread has finished its process, if nothing else holds a reference to it, the garbage collector will dispose of it automatically.
Launch a seperate thread to perform the blocking call, and terminate() it if you need to stop the thread. You can use the IOU mechanism of Threads.
Your application will not exit until all threads that have IsBackground == false
have finished.
You can use the Threads
window when the VS debugger is attached to see which threads are still running.
VS Menu: Debug -> Windows -> Threads.
I wrote the following code to keep track of which threads I have created, and warn me if any of them havn't shut down, on exit.
It works flawlessly, and it has the advantage of naming the threads within the Visual Studio debugger, which makes things easier to debug.
To use it, call the following on every thread that you create manually:
Thread x;
// Yada yada create the thread.
// Make sure you set ".IsBackground" property to "true".
x.MyRememberThreadUntilShutdown("name which is visible in VS debugger");
Then, call the following on exit:
OnShutdownCheckThreadsForExit();
Here is the helper class:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
namespace MyShared.MyHelper
{
/// <summary>
/// Helper classes for threads.
/// </summary>
public static class MyThread
{
/// <summary>
/// Remembers a thread, until shutdown.
/// On shutdown, we can double check that all of the threads we created have been shut down.
/// </summary>
/// <param name="thread">Thread we want to remember until shutdown.</param>
/// <param name="newName">New name for thread.</param>
public static void MyRememberThreadUntilShutdown(this Thread thread, string newName)
{
// Check whether the thread has previously been named
// to avoid a possible InvalidOperationException.
if (thread.Name == null)
{
thread.Name = "MyThread" + newName;
}
else
{
Console.Write("Error E20120118-1914. Unable to rename thread to \"{0}\" as it already has a name of \"{1}\".\n",
newName, thread.Name);
}
ThreadList[newName] = thread;
}
/// <summary>
/// This stores a list of all the threads we have running in the entire system.
/// </summary>
private static readonly Dictionary<string, Thread> ThreadList = new Dictionary<string, Thread>();
/// <summary>
/// On program exit, check that all of the threads we started have been exited.
/// </summary>
public static bool OnShutdownCheckThreadsForExit()
{
if (ThreadList.Count != 0)
{
foreach (var thread in ThreadList)
{
if (thread.Value.IsAlive)
{
Console.Write("Error E20120119-8152. Thread name \"{0}\" was not shut down properly on exit.\n",thread.Key);
}
}
return false;
}
else
{
return true;
}
}
}
}
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