Environment: Visual Studio .NET Beta 2, Windows 2000 SP2 .NET framework allows a lot of ways to implement multithreading program. I want to show how we can run worker thread which makes synchronous calls to user interface (for example, thread reads a long recordset and fills some control in the form). To run thread I […]
CodeGuru content and product recommendations are
editorially independent. We may make money when you click on links
to our partners.
Learn More
Environment:
Visual Studio .NET Beta 2, Windows 2000 SP2
.NET framework allows a lot of ways to implement multithreading program. I want
to show how we can run worker thread which makes synchronous calls to user
interface (for example, thread reads a long recordset and fills some control
in the form).
To run thread I use:
- Thread instance and main thread function
- Two events used to stop thread. First event is set when main thread wants
to stop worker thread; second event is set by worker thread when it really
stops.
.NET allows to call System.Windows.Forms.Control functions only from thread
where control was created. To run them from other thread we need to use
Control.Invoke (synchronous call) or Control.BeginInvoke (asynchronous call)
functions. For task like showing database records we need Invoke.
To implement this I use:
- Delegate type for calling form function, delegate instance and function
called using this delegate
- Invoke call from worker thread.
Next problem is to stop worker thread correctly. Steps to do this:
- Set event “Stop Thread��
- Wait for event “Thread is stopped”
- While waiting for event process messages using Application.DoEvents
function. This prevents deadlock because worker thread makes Invoke calls
which are processed in main thread.
Thread function checks in every iteration whether Stop Thread event is set.
If event is set, function makes clean-up operations, sets event “Thread is
stopped” and returns.
Demo project has two classes: MainForm and LongProcess. LongProcess.Run
function runs in thread and fills list box with some lines. Worker thread
may finish by natural awy or may be stopped when user presses Stop Thread
button or closes form.
Code fragments:
namespace WorkerThread
{
public delegate void DelegateAddString(String s);
public delegate void DelegateThreadFinished();
public class MainForm : System.Windows.Forms.Form
{
…
Thread m_WorkerThread;
ManualResetEvent m_EventStopThread;
ManualResetEvent m_EventThreadStopped;
public DelegateAddString m_DelegateAddString;
public DelegateThreadFinished m_DelegateThreadFinished;
…
public MainForm()
{
InitializeComponent();
m_DelegateAddString =
new DelegateAddString(this.AddString);
m_DelegateThreadFinished =
new DelegateThreadFinished(this.ThreadFinished);
m_EventStopThread = new ManualResetEvent(false);
m_EventThreadStopped = new ManualResetEvent(false);
}
…
private void btnStartThread_Click(object sender,
System.EventArgs e)
{
…
m_EventStopThread.Reset();
m_EventThreadStopped.Reset();
m_WorkerThread =
new Thread(new ThreadStart(this.WorkerThreadFunction));
m_WorkerThread.Name = “Worker Thread Sample”;
m_WorkerThread.Start();
}
private void WorkerThreadFunction()
{
LongProcess longProcess;
longProcess = new LongProcess(m_EventStopThread,
m_EventThreadStopped, this);
longProcess.Run();
}
private void StopThread()
{
if ( m_WorkerThread != null &&
m_WorkerThread.IsAlive )
{
m_EventStopThread.Set();
while (m_WorkerThread.IsAlive)
{
if ( WaitHandle.WaitAll(
(new ManualResetEvent[] {m_EventThreadStopped}),
100,
true) )
{
break;
}
Application.DoEvents();
}
}
}
private void AddString(String s)
{
listBox1.Items.Add(s);
}
private void ThreadFinished()
{
btnStartThread.Enabled = true;
btnStopThread.Enabled = false;
}
}
}
namespace WorkerThread
{
public class LongProcess
{
…
public void Run()
{
int i;
String s;
for (i = 1; i <= 10; i++)
{
s = “Step number ” + i.ToString() + ” executed”;
Thread.Sleep(400);
m_form.Invoke(m_form.m_DelegateAddString, new Object[] {s});
if ( m_EventStop.WaitOne(0, true) )
{
m_EventStopped.Set();
return;
}
}
m_form.Invoke(m_form.m_DelegateThreadFinished, null);
}
}
}
Downloads
Download demo project – 8 Kb