Synchronizing events from different threads in a console application

I feel like a complete nob asks about it, but anyway, here it is:

I was wondering what is the easiest way to synchronize events from different threads.

Code example:

class Program { static void Main(string[] args) { Console.WriteLine("# started on:" + Thread.CurrentThread.ManagedThreadId); tt t = new tt(); t.First += new EventHandler(t_First); t.Second += new EventHandler(t_Second); Task task = new Task(new Action(t.Test)); task.Start(); while (true) { Console.ReadKey(); Console.WriteLine("# waiting on:" + Thread.CurrentThread.ManagedThreadId); } } static void t_Second(object sender, EventArgs e) { Console.WriteLine("- second callback on:" + Thread.CurrentThread.ManagedThreadId); } static void t_First(object sender, EventArgs e) { Console.WriteLine("- first callback on:" + Thread.CurrentThread.ManagedThreadId); } class tt { public tt() { } public event EventHandler First; public event EventHandler Second; public void Test() { Thread.Sleep(1000); Console.WriteLine("invoked on:" + Thread.CurrentThread.ManagedThreadId); First(this, null); Thread.Sleep(1000); Second(this, null); } } } 

As you can guess, only the first script is executed in the main thread, the rest of the calls are made in the new thread created by this task.

I would like to synchronize the call with "Second" back in the main thread (it should never be called because I am blocking in the while loop). However, I would like to know how to do this or if it is possible?

+4
source share
2 answers

You can try BlockingCollection

 BlockingCollection<Action> actions = new BlockingCollection<Action>(); void main() { // start your tasks while (true) { var action = actions.Take(); action(); } } static void t_First(object sender, EventArgs e) { string message = "- first callback on:" + Thread.CurrentThread.ManagedThreadId; actions.Add(_ => Console.WriteLine(message)); } 
+5
source

If you understand correctly, you are asking how to execute code that runs on a thread in another thread. ie: you have two threads, while you are executing the second code of the thread that you want to execute in the first thread.

You can achieve this using a SynchronizationContext , for example, if you want to execute code from another thread into the main thread, you should use the current synchronization context:

 private readonly System.Threading.SynchronizationContext _currentContext = System.Threading.SynchronizationContext.Current; private readonly object _invokeLocker = new object(); public object Invoke(Delegate method, object[] args) { if (method == null) { throw new ArgumentNullException("method"); } lock (_invokeLocker) { object objectToGet = null; SendOrPostCallback invoker = new SendOrPostCallback( delegate(object data) { objectToGet = method.DynamicInvoke(args); }); _currentContext.Send(new SendOrPostCallback(invoker), method.Target); return objectToGet; } } 

While you are in the second thread, this method will execute the code in the main thread.

you can implement ISynchronizeInvoke "System.ComponentModel.ISynchronizeInvoke". check out this example.

Edit: Due to the fact that you are using a console application and therefore cannot use SynchronizationContext.Current . then you will probably need to create your own SynchronizationContext , this example that may help.

-1
source

All Articles