其实BackgroundWorker源码就是使用了AsyncOperation类的Post实现子线程更新UI,如下图:
好了,不说了,开始我们的Demo
UI布局如下:
Form1代码如下:
public partial class Form1 : Form { //异步操作对象 private AsyncOperation asyncOperation; public Form1() { InitializeComponent(); Console.WriteLine("UI初始化线程Id:" + Thread.CurrentThread.ManagedThreadId); //获取主线程异步操作对象 asyncOperation = AsyncOperationManager.CreateOperation(null); } void InvokeMainThreadMethod(object invokeMessage) { Console.WriteLine("回调的UI初始化线程Id:" + Thread.CurrentThread.ManagedThreadId); this.textBox1.Text += invokeMessage as string; } private void button1_Click(object sender, EventArgs e) { //启动线程1 Task.Run(() => { Console.WriteLine("Task1线程Id:" + Thread.CurrentThread.ManagedThreadId); Thread.Sleep(1000); //子线程更新UI asyncOperation.Post(InvokeMainThreadMethod, "Task1哈哈哈-->"); }); //启动线程2 Task.Run(() => { Console.WriteLine("Task2线程Id:" + Thread.CurrentThread.ManagedThreadId); Thread.Sleep(2000); //子线程2更新UI asyncOperation.Post(InvokeMainThreadMethod, "Task2哈哈哈");
});
} } |
其中asyncOperation.Post是子线程往主线程发送消息的核心方法,第一个参数是委托回调的方法,第二个方法的参数值
代码太简单了,就不解释了
运行结果如下:
注意线程Id的输出
可能你和我也有这样的想法,能不能主线程Post消息给子线程,如线程2,答案是不可以了,想要实现这样的效果,估计得用信号量或者AutoResetEvent了