Thread

  • Thread starter Thread starter mehdi
  • Start date Start date
M

mehdi

Hi folks,
Consider a class (MyClass) in which one of its methods (named Run) is
supposed to run in another thread, rather than the Main thread. This
class uses the System.Threading.Thread class to get the job done.
Here's the pseudo code:

class MyClass
{
void ExecAsync()
{
Start a given worker thread, say, myThreadProc.
}

void myThreadProc()
{
Run(); //An abstract method.
Fire the events, either the canceled or completed operation...
}

void Cancel()
{
//wait until the thread quits.
}
}

The question is that I've got no idea how to fire those events in the
main thread context. Any idea?

TIA,
Mehdi
 
The question is that I've got no idea how to fire those events in the
main thread context. Any idea?

Generally speaking, if you have no other design restrictions or goals,
Invoke or BeginInvoke are useful for signaling the GUI (main) thread.

Pete
 
One route is to pass an ISynchronizeInvoke to your class, which is the
approach used by System.Timers.Timer.

In simple terms, this means you can pass a form / control to your
class, and it will fire events back through the UI thread. Other sync
providers may be available ;-p

Marc



using System;
using System.ComponentModel;
using System.Threading;

static class Program
{
static void Main()
{ }
}

public abstract class ThreadedExample
{
private readonly ISynchronizeInvoke _syncInvoke;
public ThreadedExample() : this(null) { }
public ThreadedExample(ISynchronizeInvoke sync)
{
_syncInvoke = sync;
}

public event EventHandler Completed, Cancelled;
protected abstract bool Run();
public void MainMethod()
{
ThreadPool.QueueUserWorkItem(ThreadStart);
}
public void ThreadStart(object state)
{
bool success = Run();
OnEvent(success ? Completed : Cancelled, true);
}
protected void OnEvent(EventHandler handler, bool async)
{
if (handler != null)
{
if (_syncInvoke == null)
{ // no sync context; have to run sync
handler(this, EventArgs.Empty);
}
else if (async)
{
_syncInvoke.BeginInvoke(handler, new object[] { this,
EventArgs.Empty });
}
else
{
_syncInvoke.Invoke(handler, new object[] { this,
EventArgs.Empty });
}
}
}
}
 
Of course, as Peter observes, a simpler approach can be to simple fire
the events on the current thread, and make it clear to the caller that
the event will fire on an arbitrary thread and that they must
therefore deal with sync themselves locally - e.g. by using
InvokeRequired / BeginInvoke / Invoke at the caller ;-p

Additional note: using the synchronizing object approach (my last
post) you could also test InvokeRequired before firing the event -
e.g. the first block would become (leaving the rest unchanged):

if (_syncInvoke == null || !_syncInvoke.InvokeRequired)
{ // no sync context (have to run sync) or synchronize not
necessary
handler(this, EventArgs.Empty);
}

Marc
 
Of course, as Peter observes, a simpler approach can be to simple fire
the events on the current thread, and make it clear to the caller that
the event will fire on an arbitrary thread and that they must
therefore deal with sync themselves locally - e.g. by using
InvokeRequired / BeginInvoke / Invoke at the caller ;-p

Additional note: using the synchronizing object approach (my last
post) you could also test InvokeRequired before firing the event -
e.g. the first block would become (leaving the rest unchanged):

if (_syncInvoke == null || !_syncInvoke.InvokeRequired)
{ // no sync context (have to run sync) or synchronize not
necessary
handler(this, EventArgs.Empty);
}

Marc

Well, I really enjoyed the ISynchronizeInvoke interface. However, I'm
still confused about the provided code.

1. What if I never ever call the "Invoke" method?
2. What exactly Control.BeginInvoke does?
3. What does Control.EndInvoke do? Is is just supposed to get the
return value of an asynchronous function?

Any help would be highly appreciated,

Cheers,
Mehdi
 
(which incidentally is the top entry on a google search of
"Control.BeginInvoke"; just a thought...)

Marc
 
Well, I really enjoyed the ISynchronizeInvoke interface. However, I'm
still confused about the provided code.

1. What if I never ever call the "Invoke" method?
2. What exactly Control.BeginInvoke does?
3. What does Control.EndInvoke do? Is is just supposed to get the
return value of an asynchronous function?

Any help would be highly appreciated,

Cheers,
Mehdi

For those who are familiar with Win32, the short answer is that
Control.BeginInvoke actually calls the PostMessage API, while the
Invoke method calls the SendMessage API.

HTH,
Mehdi
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Similar Threads


Back
Top