对于窗体程序,使用基于任务的异步模式需要用到Task类,下面示例下非常简单的用法。
1.创建一个拥有异步方法的类
该类拥有一个异步方法DoSomthingAsync,根据微软建议的命名规则该方法要带Async后缀
public class Dog { public Task DoSomthingAsync() { Task task = Task.Run(() => { Console.WriteLine("后台任务开始运行"); Thread.Sleep(5000); Console.WriteLine("后台任务运行结束"); }); return task; } }
当调用该方法的时候,就是异步执行的。为了在该方法执行完成后做进一步处理,需要写一个任务完成后的程序来做点事情,比如更新UI控件。
2.创建任务完成后需要执行的方法
using System; using System.Threading; using System.Threading.Tasks; using System.Windows.Forms; namespace TaskTest { public partial class Form1 : Form { public Form1() { InitializeComponent(); } /// ///任务完成后要执行的方法,更新UI /// private void OnDoSomthingIsComplete(Task t) { Action action = () => { textBox.Text = "任务完成后显示这段文字到UI控件"; }; textBox.Invoke(action); } } }
对于上面定义的这个OnDoSonthingIsComplete方法,我采用了类似于事件方式的命名规则。
另外,这个方法也和使用BackgroundWorker类一样,并不是在调用者线程上执行的,而是在异步线程中执行的。这就是为什么需要使用textBox.Invoke方法。
3.调用该类的异步方法
在button按下的时候调用。这里把上面所有的代码都整合在一起了。
using System; using System.Threading; using System.Threading.Tasks; using System.Windows.Forms; namespace TaskTest { public partial class Form1 : Form { public Form1() { InitializeComponent(); } private void OnDoSomthingIsComplete(Task t) {//这里的参数:Task t 在下面执行的时候其实就是dog.DoSomthingAsync() Action action = () => { textBox.Text = "任务完成后显示这段文字到UI控件"; }; textBox.Invoke(action); } private void button1_Click(object sender, EventArgs e) { Dog dog = new Dog(); Task task = dog.DoSomthingAsync().ContinueWith(OnDoSomthingIsComplete); } } /// <summary> /// Dog类 /// </summary> public class Dog { public Task DoSomthingAsync() { Task task = Task.Run(() => { Console.WriteLine("后台任务开始运行"); Thread.Sleep(5000); Console.WriteLine("后台任务运行结束"); }); return task; } } }
执行效果如下:
最后再说明下,对于任务执行完成后要执行处理程序,可不不用显式指定方法名,下面用lambda方式会更简练:
private void button1_Click(object sender, EventArgs e) { Dog dog = new Dog(); Task task = dog.DoSomthingAsync().ContinueWith((Task t)=> { Action action = () => { textBox.Text = "任务完成后显示这段文字到UI控件"; }; textBox.Invoke(action); }); }