C# async await 学习笔记1(http://www.cnblogs.com/siso/p/3691059.html)
提到了ThreadId是一样的,突然想到在WinForm中,非UI线程是无法直接更新UI线程上的控件的问题。
于是做了如下测试:
using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Linq; using System.Text; using System.Windows.Forms; using System.Threading.Tasks; using System.Threading;namespace WindowsFormsApplication1 {public partial class Form1 : Form{public Form1(){InitializeComponent();}Task<string> LongTimeTask(){tbResult.Text += "LongTimeTask开始:" + DateTime.Now.ToString() + " "; Task<string> task = new Task<string>(() => { Thread.Sleep(5000); return "这是任务返回值"; });task.Start();tbResult.Text += "LongTimeTask结束:" + DateTime.Now.ToString() + " "; return task;}async void AsyncCall(){tbResult.Text += "AsyncCall开始:" + DateTime.Now.ToString() + " "; string result = await LongTimeTask(); //await调用的方法需要返回Task或Task,且调用await所在的方法要有async关键字 tbResult.Text += "AsyncCall:" + result + " "; tbResult.Text += "AsyncCall结束:" + DateTime.Now.ToString() + " "; } private void button1_Click(object sender, EventArgs e){tbResult.Text += "Main开始:" + DateTime.Now.ToString() + " ";AsyncCall();tbResult.Text += "Main结束:" + DateTime.Now.ToString() + " ";}} }
发现,在AsyncCall中,可以直接访问TextBox(tbResult),如果对上面的测试觉得没什么奇怪,大家可以先看下面的代码。
using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Linq; using System.Text; using System.Windows.Forms; using System.Threading;namespace WindowsFormsApplication1 {public partial class Form2 : Form{public Form2(){InitializeComponent();}void LongTimeTask(){Thread.Sleep(5000);tbResult.Text += "AsyncCall结束:" + DateTime.Now.ToString() + " ";} private void button1_Click(object sender, EventArgs e){tbResult.Text += "Main开始:" + DateTime.Now.ToString() + " ";Thread t = new Thread(LongTimeTask);t.Start();tbResult.Text += "Main结束:" + DateTime.Now.ToString() + " ";}} }
运行到 LongTimeTask的tbResult.Text时,提示:线程间操作无效: 从不是创建控件“tbResult”的线程访问它。
为了能在非UI线程中访问到UI线程中的控件,于是需作如下修改:
using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Linq; using System.Text; using System.Windows.Forms; using System.Threading;namespace WindowsFormsApplication1 {public partial class Form2 : Form{delegate void UpdateUIDelegate();UpdateUIDelegate updateUIDelegate; public Form2(){InitializeComponent();updateUIDelegate = new UpdateUIDelegate(UpdateUI);}void UpdateUI(){if (tbResult.InvokeRequired){tbResult.Invoke(updateUIDelegate);}else{tbResult.Text += "AsyncCall结束:" + DateTime.Now.ToString() + " ";}}void LongTimeTask(){Thread.Sleep(5000);UpdateUI(); } private void button1_Click(object sender, EventArgs e){tbResult.Text += "Main开始:" + DateTime.Now.ToString() + " ";Thread t = new Thread(LongTimeTask);t.Start();tbResult.Text += "Main结束:" + DateTime.Now.ToString() + " ";}} }