MIke Brown wrote:
Hello all,
I've been searching for a solution on google for a problem related to
creating events from a worker thread, with no luck..
Basically, the problem is when my events are caught by a UI using my
class, they get the usual "Control 'blah' accessed from a thread other
than the thread it was created on.". I understand that of course, but
my class is to be distributed to people who don't want to have to worry
about invoking delegates in the event handler, I want to keep it all
neat and tidy inside the class and they can do whatever they want in
the events I throw. Is there a way to launch my event on the thread the
class was created on, instead of my worker thread? I've tried using a
delegate thinking that would work, but it doesn't. I've also tried
inheriting from Control and using Invoke, which doesn't seem to work as
well.
Is there something I'm missing to easily accomplish this within my
class?
<?
....
public myclass()
{
readThread = new Thread(new ThreadStart(Thr eadLoop));
}
public void ThreadLoop()
{
while(some waithandle)
{
if(something)
if(myevent!=nul l) myevent(this, new args(1,2,3,4));
// instead of calling the above event here, I need to trigger
something
// in the thread the class was created on (UI Thread).
}
}
....
?>
Thanks!
Michael Brown
360 Replays Ltd.
Hi,
You need to have access to one of your UI Controls inside your thread.
This enables you to invoke your delegate in the UI thread. I can think
of 2 ways to do this:
(1)
In my applications I usually have some sort of service for this, which
is initialized at startup:
using System;
using System.Threadin g;
using System.Windows. Forms;
namespace ConsoleApplicat ion
{
static class ApplicationHost
{
public static void Invoke(Delegate method, params object[] args)
{
aControlInTheUi Thread.Invoke(m ethod, args);
}
public static void BeginInvoke(Del egate method,
params object[] args)
{
aControlInTheUi Thread.BeginInv oke(method, args);
}
// initialiaized at startup
private static Control aControlInTheUi Thread;
}
class Program
{
static void Main()
{
ThreadHelper helper = new ThreadHelper();
Thread readThread =
new Thread(new ThreadStart(hel per.ThreadLoop) );
}
}
class ThreadHelper
{
private bool something = false;
public EventHandler SomeEvent;
public void ThreadLoop()
{
while(true)
{
if(something)
{
ApplicationHost .Invoke(
new RaiseSomeEventI nUiThreadHandle r(
RaiseSomeEventI nUiThread)
;
}
}
}
private delegate void RaiseSomeEventI nUiThreadHandle r();
private void RaiseSomeEventI nUiThread()
{
if (SomeEvent != null)
SomeEvent(this, EventArgs.Empty );
}
}
}
(2)
Pass a control as an argument into your thread:
namespace ConsoleApplicat ion
{
class Program
{
static void Main()
{
Control ctrl = null;// Some control of the GUI,
// e.g. main form
ThreadHelper helper = new ThreadHelper(ct rl);
Thread readThread =
new Thread(new ThreadStart(hel per.ThreadLoop) );
}
}
class ThreadHelper
{
public ThreadHelper(Co ntrol ctrlInUiThread)
{
this.ctrlInUiTh read = ctrlInUiThread;
}
private Control ctrlInUiThread;
private bool something = false;
public EventHandler SomeEvent;
public void ThreadLoop()
{
while(true)
{
if(something)
{
ctrlInUiThread. Invoke(
new RaiseSomeEventI nUiThreadHandle r(
RaiseSomeEventI nUiThread)
);
}
}
}
private delegate void RaiseSomeEventI nUiThreadHandle r();
private void RaiseSomeEventI nUiThread()
{
if (SomeEvent != null)
SomeEvent(this, EventArgs.Empty );
}
}
}
HTH,
Andy