analyze a thread



Hi, could somebody analyze a class and suggest what to do to avoid hanging the class (thread) when the application calling it exits? (Other than using background threads). This class is something similar to a splash screen. Thanks


using System;
using System.Drawing;
using System.Windows.Forms;
using System.Threading;
using System.Reflection;
using System.IO;

namespace CF.GUI {

/// <summary>
/// Displays a "connecting" window with animation of signal sent between two computers.
/// The window is shown only if a second has passed since it was called.
/// </summary>
/// <remarks>
/// Warning! Disables the parent form, if Hide() isn't called the parent form will be frozen!
/// Always use try-finally block.</remarks>
/// <example>
/// ConnectionForm f = null;
/// try {
/// f = new ConnectionForm(this);
/// f.Show();
/// // do something in the main thread
/// } finally {
/// f.Hide();
/// f.Dispose();
/// f = null;
/// }
/// </example>
public class ConnectionForm : Form, IDisposable {



private Size size;
private Point computer1;
private Point computer2;
private Point computer1Attach;
private Point computer2Attach;
private Point textLocation;
private Rectangle invRect;

private bool modal;


/// <summary>
/// position of "signal" in the network
/// </summary>
private int signalPosition;


/// <summary>
/// length of the "signal"
/// </summary>
private const int signalLength = 10;


/// <summary>
/// in which direction does the "signal" travel
/// </summary>
private bool signalDirectionRight = true;


private Form owner = null;


private Icon icon;


private Thread threadShow;
private Thread threadAnimate;

private string caption;

public ConnectionForm(Form owner) {

try {

this.owner = owner;
this.owner = null;

this.size = new Size(200, 60);
this.computer1 = new Point(8, 15);
this.computer1Attach = new Point(28, 30);
this.computer2 = new Point(160, 15);
this.computer2Attach = new Point(180, 30);
this.textLocation = new Point(70, 4);
this.invRect = new Rectangle(computer1Attach.X, computer1Attach.Y - 1, computer2Attach.X, computer2Attach.Y + 1);

this.FormBorderStyle = FormBorderStyle.None;
this.BackColor = Color.White;
this.Cursor = Cursors.WaitCursor;
this.ControlBox = false;
this.HelpButton = false;
this.MaximizeBox = false;
this.MinimizeBox = false;
this.ShowInTaskbar = false;
this.Size = size;
this.StartPosition = FormStartPosition.CenterScreen;


this.Text = "Scania CF System";
this.TopLevel = true;
this.TopMost = true;
this.SetStyle(
ControlStyles.AllPaintingInWmPaint |
ControlStyles.DoubleBuffer |
ControlStyles.Opaque |
ControlStyles.UserPaint,
true);

caption = "Connecting...";
ICFModuleClient cf = CF.CFModuleSingleton.CFClient;
if (cf != null)
caption = cf.Captions.get("CF.GUI.ConnectingForm:Caption");

Assembly executingAssembly = Assembly.GetExecutingAssembly();
Stream resourceStream = executingAssembly.GetManifestResourceStream( "CF.GUI.images.computer.ico" );
icon = new Icon(resourceStream);
} catch {}
}


~ConnectionForm() {
if (owner != null) {
try {
owner.Enabled = true;
} catch { }
owner = null;
}
}


// TODO: override or what?
public void Dispose() {
if (owner != null) {
try {
owner.Enabled = true;
} catch { }
owner = null;
}
base.Dispose(true);
}


/// <summary>
/// Displays the form. Starts new thread, so doesn't block
/// </summary>
public new void Show() {
Show(true);
}


/// <summary>
/// Displays the form. Starts new thread, so doesn't block
/// </summary>
public void Show(bool modal) {
this.modal = modal;
if (modal) owner = null;

if (owner != null) {
try {
owner.Enabled = false;
} catch { }
}

try {
threadShow = new Thread(new ThreadStart(threadShowRun));
threadShow.Start();

threadAnimate = new Thread(new ThreadStart(threadAnimateRun));
threadAnimate.Start();
} catch { }
}


/// <summary>
/// Closes the form
/// </summary>
public new void Hide() {
// TODO: invoke Hide()? It's called from an other thread I suppose? Or not?
if (owner != null) {
try {
owner.Enabled = true;
} catch { }
owner = null;
}

int trials = 50;
bool success = false;
while (!false && (trials-- > 0) ) {
try {
this.Close();
success = true;
} catch {
Console.WriteLine("ERROR1");
}
if (!success) {
Thread.Sleep(20);
}
}
try {
threadAnimate.Abort();
threadShow.Abort();
this.Dispose();
} catch (Exception e) {
Console.WriteLine ("ERROR2" + e.Message);
}
}



private void threadShowRun() {
try {
// do not show window if time is less than one second
Thread.Sleep(1000);
if (modal)
this.ShowDialog();
else
this.Show();
} catch { }
}


private void threadAnimateRun() {
try {
signalPosition = computer1Attach.X;
signalDirectionRight = true;
while (true) {
if (signalDirectionRight) {

// send "signal"
if (signalPosition < computer2Attach.X) {
signalPosition += 6;
} else {
signalDirectionRight = false;
}

} else {

// send "signal"
if (signalPosition > computer1Attach.X) {
signalPosition -= 6;
} else {
signalDirectionRight = true;
}

}

Invoke(new MethodInvoker(Invalidate), new object[] {invRect});
Thread.Sleep(100);
}
} catch { }
}


private Bitmap backBuffer;

protected override void OnPaint(PaintEventArgs e) {
try {
if (backBuffer == null) {
backBuffer = new Bitmap(size.Width, size.Height);
}
Graphics g = Graphics.FromImage(backBuffer);

g.Clear(Color.White);
g.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.None;

// draw border
Pen p = new Pen(Color.Black, 1);
g.DrawRectangle(p, 0, 0, size.Width - 1, size.Height - 1);

// draw text
g.DrawString(caption, new Font("Verdana", 7), Brushes.Black, textLocation);

// draw animation
Pen p1 = new Pen(Color.Black, 3);
Pen p2 = new Pen(Color.White, 1);
g.DrawLine(p1, computer1Attach, computer2Attach);
int y = computer1Attach.Y;
g.DrawLine(p2, signalPosition, y, signalPosition - signalLength, y);
g.DrawIcon(icon, computer1.X, computer1.Y);
g.DrawIcon(icon, computer2.X, computer2.Y);

g.Dispose();
e.Graphics.DrawImageUnscaled(backBuffer, 0, 0);
} catch { }
}


protected override void OnPaintBackground(PaintEventArgs e) {
// don't allow the background to paint
}


}
}
.