how to invoke method in thread from different thread?

P

Peter Rilling

Okay, I have the main thread which does all the work. This main thread
spawns a worker thread that just periodically poles the environment looking
for a certain condition. This second thread is very small, and only is
responsible for raising a flag when the environment changes.

What I want is for the main thread to raise an event when the change has
been flagged. I other words, I want the main thread to raise the event, not
this small worker thread. How can the worker thread talk to the main thread
so the resulting event can actually be raised in the main thread, not the
worker thread?
 
J

Jon Skeet [C# MVP]

Peter Rilling said:
Okay, I have the main thread which does all the work. This main thread
spawns a worker thread that just periodically poles the environment looking
for a certain condition. This second thread is very small, and only is
responsible for raising a flag when the environment changes.

What I want is for the main thread to raise an event when the change has
been flagged. I other words, I want the main thread to raise the event, not
this small worker thread. How can the worker thread talk to the main thread
so the resulting event can actually be raised in the main thread, not the
worker thread?

The main thread would need to be "watching" for work to be done -
either periodically looking at a list of some kind or even just waiting
for items from that list, and doing nothing else.

The latter is a producer/consumer type of setup - see
http://www.pobox.com/~skeet/csharp/threads/deadlocks.shtml about half
way down.

The former is very similar, just without the waiting.
 
G

Guest

public delegate void TestDelegate(string name);
namespace ConditionChecker
{
public class TestApp
{
static TestApp _instance;
public event EventHandler ConditionMet;

public static TestApp Instance
{
get
{
lock(typeof(TestApp))
{
if (_instance == null) _instance = new TestApp();
}
return _instance;
}
}


[STAThread]
static void Main(string[] args)
{
System.Threading.Thread.CurrentThread.Name = "TestApp";
ConditionChecker cond = new ConditionChecker();
CheckDelegate del = new CheckDelegate(cond.Check);
del.BeginInvoke(null, null);
while(true)
{
if (TestApp.Instance.ConditionMet != null)
lock(TestApp.Instance)
{
TestApp.Instance.ConditionMet(null ,EventArgs.Empty);
}
}
}
}

public class ConditionChecker
{
public void HandleCondition(object sender, EventArgs e)
{
lock(this)
{
System.Console.WriteLine(string.Format("Condition Handled in
{0} @ {1}",
System.Threading.Thread.CurrentThread.Name,
DateTime.Now.TimeOfDay.ToString()));
TestApp.Instance.ConditionMet -= new
EventHandler(this.HandleCondition);
}
}
public void Check()
{
int i = 1;
System.Threading.Thread.CurrentThread.Name = "ConditionChecker";
while(true)
if (((i++) % 1000000) == 0)
{
System.Console.WriteLine("Condition Met in {0}",
System.Threading.Thread.CurrentThread.Name);
TestApp.Instance.ConditionMet += new
EventHandler(HandleCondition);
i = 1;
}

}
}

delegate void CheckDelegate();
}
 
G

Guest

namespace ConditionChecker
{
public class TestApp
{
static TestApp _instance;
public event EventHandler ConditionMet;

public static TestApp Instance
{
get
{
lock(typeof(TestApp))
{
if (_instance == null) _instance = new TestApp();
}
return _instance;
}
}


[STAThread]
static void Main(string[] args)
{
System.Threading.Thread.CurrentThread.Name = "TestApp";
ConditionChecker cond = new ConditionChecker();
CheckDelegate del = new CheckDelegate(cond.Check);
del.BeginInvoke(null, null);
while(true)
{
if (TestApp.Instance.ConditionMet != null)
lock(TestApp.Instance)
{
TestApp.Instance.ConditionMet(null ,EventArgs.Empty);
}
}
}
}

public class ConditionChecker
{
public void HandleCondition(object sender, EventArgs e)
{
lock(this)
{
System.Console.WriteLine(string.Format("Condition Handled in
{0} @ {1}",
System.Threading.Thread.CurrentThread.Name,
DateTime.Now.TimeOfDay.ToString()));
TestApp.Instance.ConditionMet -= new
EventHandler(this.HandleCondition);
}
}
public void Check()
{
int i = 1;
System.Threading.Thread.CurrentThread.Name = "ConditionChecker";
while(true)
if (((i++) % 1000000) == 0)
{
System.Console.WriteLine("Condition Met in {0}",
System.Threading.Thread.CurrentThread.Name);
TestApp.Instance.ConditionMet += new
EventHandler(HandleCondition);
i = 1;
}

}
}

delegate void CheckDelegate();
}
 
G

Guest

dont know how this line got in there:
public delegate void TestDelegate(string name);


here is the code:

=======================================
namespace ConditionChecker
{
public class TestApp
{
static TestApp _instance;
public event EventHandler ConditionMet;

public static TestApp Instance
{
get
{
lock(typeof(TestApp))
{
if (_instance == null) _instance = new TestApp();
}
return _instance;
}
}


[STAThread]
static void Main(string[] args)
{
System.Threading.Thread.CurrentThread.Name = "TestApp";
ConditionChecker cond = new ConditionChecker();
CheckDelegate del = new CheckDelegate(cond.Check);
del.BeginInvoke(null, null);
while(true)
{
if (TestApp.Instance.ConditionMet != null)
lock(TestApp.Instance)
{
TestApp.Instance.ConditionMet(null ,EventArgs.Empty);
}
}
}
}

public class ConditionChecker
{
public void HandleCondition(object sender, EventArgs e)
{
lock(this)
{
System.Console.WriteLine(
string.Format("Condition Handled in {0} @ {1}",
System.Threading.Thread.CurrentThread.Name,
DateTime.Now.TimeOfDay.ToString()));
TestApp.Instance.ConditionMet -=
new EventHandler(this.HandleCondition);
}
}
public void Check()
{
int i = 1;
System.Threading.Thread.CurrentThread.Name = "ConditionChecker";
while(true)
if (((i++) % 1000000) == 0)
{
System.Console.WriteLine("Condition Met in {0}",
System.Threading.Thread.CurrentThread.Name);
TestApp.Instance.ConditionMet +=
new EventHandler(HandleCondition);
i = 1;
}

}
}

delegate void CheckDelegate();
}
 
G

Guest

Peter,

Are you working in a windows Form? If so, then I'd recommend that the
simplest solution is to use "Invoke" to directly call the parent thread from
the worker thread.

http://www.yoda.arachsys.com/csharp/threads/winforms.shtml

There's a bit of typing in setting up the delegate, but I still think it's
the shortest and simplest solution.

The invoked method in the parent thread would look like this...

void OnCondition()
{
myEvent(); // Raise the event
}

and the call in the worker thread would look like...

if (conditionDetected)
{
Invoke(OnConditionDelegate);
}

Note that you can invoke a method with, or without, arguments.

HTH,

Javaman
 

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

Top