同步控制台应用程序中不同线程的事件

我感觉像是一个总的菜鸟问这个,但无论如何,它在这里:

我想知道从不同线程同步事件的最简单方法是什么。

一些示例代码:

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); } } } 

正如你可能猜到的那样,只有第一个writeline在主线程上执行,其他的调用都在任务创建的新线程上执行。

我想在主线程上同步调用“Second”(它应该永远不会被调用,因为我在while循环中阻塞)。 但是,我想知道这样做的方式,或者它是否可能?

你可以尝试一下BlockingCollection

 BlockingCollection actions = new BlockingCollection(); 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)); } 

如果我理解你是对的,那么你就是在询问如何将在线程上运行的代码执行到不同的线程中。 即:你有两个线程,而你正在执行第二个线程代码,你想在第一个线程中执行它。

您可以通过使用SynchronizationContext来实现此目的,例如,如果要将代码从另一个线程执行到主线程,则应使用当前同步上下文:

 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; } } 

当您处于第二个线程时,使用此方法将在主线程上执行代码。

您可以实现ISynchronizeInvoke “System.ComponentModel.ISynchronizeInvoke”。 查看这个例子。

编辑:由于您正在运行控制台应用程序,因此无法使用SynchronizationContext.Current 。 那么你可能需要设计自己的SynchronizationContext , 这个例子可能有所帮助。