winfrom程序中很多地方需要用到异步操作,比如用户的登陆,在登陆的时候,登陆界面是锁定了,不允许任何的操作,但如果用户这时想取消登录,出来关闭程序外,就没有其他方式了。好在可以通过异步操作来实现登录的时候,让用户点击取消按钮来达到取消登录的目的。
1、通过线程来实现异步操作:
private void Button_Click(object sender, RoutedEventArgs e) { WaiteWin ww = new WaiteWin(); new Thread(o => { TestTask(10000);//假设点击按钮后的操作需要10秒来完成 //下面通过一个异步委托来执行指定的操作OutputInfo,这个操作有两个参数<Button, WaiteWin>,传递的实参为 sender, ww //这个操作是在前面的TestTask执行完成后执行的操作 Dispatcher.BeginInvoke(DispatcherPriority.Normal, new Action<Button, WaiteWin>(OutputInfo), sender, ww); }) {//需要注意的就是IsBackground默认为false,也就是该线程对调用它的线程不产生依赖,当调用线程退出时该线程也不会结束。 //因此需要将IsBackground设置为true以指明该线程是后台线程,这样当主线程退出时该线程也会结束。 IsBackground = true } .Start();//这一步以后的操作是在TestTask执行的同时执行的操作 ww.ShowDialog(); }
上面的代码实现了这样一个功能,就是在点击按钮实现操作TestTask的时候,这个操作可能会花费很长一段时间,这时通过弹出一个提示用户等待的框框ww,来提高用户体验。
在这个按钮事件中,TestTask方法和start()后面的代码是同时执行的,当testtask里面的操作完成后,程序进入outputinfo方法中去关闭提示框。
2、线程池来实现异步操作
线程池的实现方式和上面的差不多
private void Button_Click_1(object sender, RoutedEventArgs e) { WaiteWin ww = new WaiteWin(); ThreadPool.QueueUserWorkItem (s=>{ TestTask(5000); Dispatcher.BeginInvoke(DispatcherPriority.Normal,new Action<Button,WaiteWin>(OutputInfo), sender, ww); }); ww.ShowDialog(); }
3、使用async/await进行异步操作
private async void Button_Click_2(object sender, RoutedEventArgs e) { WaiteWin ww = new WaiteWin(); Task t = new Task(() => { TestTask(5000); }); t.Start();
ww.ShowDialog();
await t;
ww.closeMe(); }
这种方式和上面的两种方式有一个很大的不同之处,就是程序在执行到await t 的时候,就返回了,因此要和testtask操作同时执行的操作就必须放在await t这条语句之前,在这条语句之后的操作都会在执行完testtask后才执行,因此用这种方式就不能用来弹出提示框了,因为弹出了提示框需要用户手动的去关闭才会继续执行后面的操作,否则程序不会执行await t以后的操作,即不能实现自动关闭提示框,因为程序一直在await t这个地方等着的。还有一点要注意的是,要使用await这个功能,必须是在.NET 4以后的版本才可以用,如果是之前的版本是没法用的。
但是可以这样做
private void Button_Click_2(object sender, RoutedEventArgs e) { WaiteWin ww = new WaiteWin(); Task t = new Task(() => { TestTask(5000); }); t.Start(); //在这里可以执行其他需要与TestTask同时执行的操作 t.Wait(); //或者用这个Task.WaitAll(t); ww.ShowDialog(); }
总结:三种方式,在程序执行testtask的时候,用户都可以对界面做其他操作,但是第三种方式如果是弹出的一个提示框,那么在程序执行完testtask的时候,它不会自动的去关闭提示框,因为线程一直在t.wait()这个地方等着,等着提示框被关闭,所以除非是手动去关闭,否则程序会一直等待下去。
原文:http://www.cnblogs.com/jin-/p/5021632.html