c# 委托与异步调用
2018-06-17 21:18:18来源:未知 阅读 ()
背景:在winform UI中,有时需要对控件进行比较频繁的刷新,如进度条、picturebox显示视频等。如果在主线程进行这些刷新操作,操作还未完成就将执行下一次刷新,程序将发生错误;如果只是创建另一个线程执行这些操作,将和主线程产生竞争,造成界面锁死(因此windows GUI编程有一个规则,就是只能通过创建控件的线程来操作控件的数据,否则就可能产生不可预料的结果)。这时候,我们就可以用委托与异步来解决这个问题。
委托:回顾一下委托 ,一、定义委托,委托定义的参数与传递给委托的方法的参数一致。二、声明与实例化。三、调用,将委托作为参数供方法调用。
异步:Windows窗体控件,唯一可以从创建它的线程之外的线程中调用的是Invoke()、BeginInvoke()、EndInvoke()方法和InvokeRequired属性。这些方法会切换到创建控件的线程上,以调用赋予一个委托参数的方法,该委托参数可以传递给这些方法。
关于Invoke()与BeginInvoke():其中BeginInvoke()、EndInvoke()方法是Invoke()方法的异步版本。相同点:都需要一个委托对象作为参数。不同点:Invoke()是同步方法,Invoke封送的方法被执行完毕前,Invoke()不会返回,从而调用者线程将被阻塞;需要等待UI操作执行完毕后继续执行线程时考虑使用。而BeginInvoke()相反,是异步方法,方法调后立即返回,不用等待委托方法的执行结束,主线程就不会阻塞。
Delegate.BeginInvoke方法从ThreadPool取出一个线程来执行这个方法,以获得异步执行效果。Control.BeginInvoke方法并不会另开线程。
参考:http://blog.csdn.net/stxyc/article/details/16945581
初学C#,理解的不是很透彻,一步一步来,循序渐进。
下面是一个进度条的小程序:
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; namespace progressBar { public partial class Form1 : Form { delegate void ShowProgressDelegate(); delegate void RunTaskDelegate(); public Form1() { InitializeComponent(); this.progressBar1.Maximum = 50; this.progressBar1.Step = 1; } private void startBtn_Click(object sender, EventArgs e) { RunTaskDelegate runTask = new RunTaskDelegate(RunTask); // 委托异步调用方法 runTask.BeginInvoke(null, null); } private void closeBtn_Click(object sender, EventArgs e) { this.Close(); } //进度条增加 void ShowProgress() { this.progressBar1.PerformStep(); } //模拟工作方法 public void RunTask() { ShowProgressDelegate showProgress = new ShowProgressDelegate(ShowProgress); int iTotal = 50;//工作量 for (int i = 0; i < iTotal; i++) { System.Threading.Thread.Sleep(1000);//模拟工作 this.BeginInvoke(showProgress); } } } }
我目前的理解是:RunTaskDelegate的作用是从另一个线程调用RunTask()方法(此方法中包含主线程的休眠),可以避免休眠期间界面无响应。ShowProgressDelegate的作用就是异步调用ShowProgress()方法,从而避免非UI线程操作控件产生的异常。
标签:
版权申明:本站文章部分自网络,如有侵权,请联系:west999com@outlook.com
特别注意:本站所有转载文章言论不代表本站观点,本站所提供的摄影照片,插画,设计作品,如需使用,请与原作者联系,版权归原作者所有
上一篇:网络电视精灵
- PHP 使用 Swoole - TaskWorker 实现异步操作 Mysql 2019-09-23
- 用PHP调用微博接口实现微博登录,可参考学习下! 2019-08-23
- Swoole异步投递task任务 2019-07-24
- Redis高可用及分片集群 2018-07-19
- 使用GTID给Galera集群做数据库异步复制 2018-07-16
IDC资讯: 主机资讯 注册资讯 托管资讯 vps资讯 网站建设
网站运营: 建站经验 策划盈利 搜索优化 网站推广 免费资源
网络编程: Asp.Net编程 Asp编程 Php编程 Xml编程 Access Mssql Mysql 其它
服务器技术: Web服务器 Ftp服务器 Mail服务器 Dns服务器 安全防护
软件技巧: 其它软件 Word Excel Powerpoint Ghost Vista QQ空间 QQ FlashGet 迅雷
网页制作: FrontPages Dreamweaver Javascript css photoshop fireworks Flash