C#多线程和异步(三)——一些异步编程模式
内容导读
互联网集市收集整理的这篇技术教程文章主要介绍了C#多线程和异步(三)——一些异步编程模式,小编现在分享给大家,供广大互联网技能从业者学习和参考。文章包含3771字,纯文字阅读大概需要6分钟。
内容图文
![C#多线程和异步(三)——一些异步编程模式](/upload/InfoBanner/zyjiaocheng/1313/12ef27faff8f46269bb75b71e98bff26.jpg)
一、任务并行库
任务并行库(Task Parellel Library)是BCL中的一个类库,极大地简化了并行编程,这里以Parallel.For和Parallel.ForEach为例。在C#中for/foreach循环使用十分普遍,如果迭代不依赖与上次迭代的结果时,把迭代放在 不同的处理器上并行处理 将很大地提高运行效率,Parallel.For和Parallel.ForEach就是为这个目的而设计的。
一个栗子:
1 static void Main(string[] args) 2 { 3//Parallel.For 计算0到10的平方 4 Parallel.For(1, 6, i => 5 { 6 Console.WriteLine("The square of {0} is {1}", i, i * i); 7 }); 8 9//Parallel.ForEach 计算每个字符串的长度10string[] strs = { "We", "hold", "these", "truths" }; 11 Parallel.ForEach(strs, i => Console.WriteLine("{0} has {1} letters",i,i.Length)); 12 Console.ReadKey(); 13 }
运行结果:
二、计时器(Timer)
计时器提供了一种 定期重复运行异步方法 的方式,当计时器到期后,系统从线程池中的线程上开启一个回调方法,把state作为参数,并开始运行。
Timer最常用的构造函数如下:
Timer(TimeCallback callback,object state,uint dueTime, uint period)
callback是一个返回值为void的委托,state为传入callback的参数,dueTime为第一次调用前的时间,period为两次调用的时间间隔
一个栗子:
1 class Program 2 { 3 int count = 0; 4void Run(object state) 5 { 6 Console.WriteLine("{0},已经调用了{1}次了", state, ++count); 7 } 8staticvoid Main(string[] args) 9 { 10 Program p = new Program(); 11//2000毫秒后开始调用,每次间隔1000毫秒12 Timer timer = new Timer(p.Run, "hello", 2000, 1000); 13 Console.WriteLine("Timer start"); 1415 Console.ReadLine(); 16 } 17 }
执行结果:
三、委托执行异步
使用委托执行异步,使用的是引用方法,如果一个委托对象在调用列表中只有一个方法(这个方法就是引用方法),它就可以异步执行这个方法。委托类有两个方法BeginIvoke和EndInvoke。
BeginInvoke :执行BeginInvoke方法时,会线程池中获取一个独立线程来执行引用方法,并立即返回到原始线程一个实现IAsyncResult接口的对象的引用(该对象包含了线程池中线程运行异步方法的状态),原始线程继续执行,而引用方法在线程池的线程中并行执行。
EndInvoke : 获取异步方法调用返回的值,并释放资源,该方法把异步方法的返回值作为自己的返回值。
委托执行异步编程的3种模式:
等待一直到完成(wait-until-done):在发起了异步方法,原始线程执行到EndInvoke时就中断并且等异步方法完成完成后再继续。
轮询(polling):原始线程定期检查发起的线程是否完成(通过IAsyncResult.IsCompleted属性判断),如果没有则继续进行原始线程中的任务。
回调(callback):原始线程一直执行,无需等待或检查发起的线程是否完成,在发起的线程中的引用方法完成之后,发起线程会调用回调方法,由回调方法在调用EndInvoke之前处理异步方法的结果。
①等待一直到完成模式
原始线程执行到EndInvoke,如果异步任务没有完成就一直等待
1 delegate int MyDel(int first,int second);//委托声明 2class Program 3 { 4staticint Sum(int x, int y) 5 { 6 Thread.Sleep(1000); 7return x + y; 8 } 9staticvoid Main(string[] args) 10 { 11 MyDel del = Sum; 12//调用异步操作(第三个参数是回调函数,第四个参数是额外的值)13 IAsyncResult iar = del.BeginInvoke(3, 5, null, null); 1415//doSomehing... 1617//☆☆☆ 执行EndInvoke,如果引用方法Sum没有执行完成,主线程就等待其完成18int result = del.EndInvoke(iar); 19 Console.WriteLine(result); 20 } 21 }
②轮询模式
定期查询任务是否完成:
1 delegate int MyDel(int first,int second);//委托声明 2class Program 3 { 4staticint Sum(int x, int y) 5 { 6 Thread.Sleep(1000); 7return x + y; 8 } 9staticvoid Main(string[] args) 10 { 11 MyDel del = Sum; 12 IAsyncResult iar = del.BeginInvoke(3, 5, null, null); 1314//☆☆☆ 通过iar.IsCompleted定期查询完成状态15while (!iar.IsCompleted)//IsCompleted表示调用的异步操作是否完成16 { 17//doSomething18 Thread.Sleep(300); 19 Console.WriteLine("no done"); 20 } 21int result = del.EndInvoke(iar); 22 Console.WriteLine(result); 23 Console.ReadKey(); 24 } 25 }
③回调模式
原始线程执行委托的BeginInvoke后就不管新线程的事了,委托中的引用方法执行完成后,在回调函数中获取结果并处理,执行委托的EndInvoke方法
1 delegate int MyDel(int first,int second);//委托声明 2class Program 3 { 4staticint Sum(int x, int y) 5 { 6 Thread.Sleep(1000); 7return x + y; 8 } 910//回调方法的签名和返回值类型必须和AsyncCallBack委托类型一致 11//输入参数为IAsyncResult,返回值是Void类型12staticvoid CallWhenDone(IAsyncResult iar){ 13 AsyncResult ar = (AsyncResult)iar; 14 MyDel del = (MyDel)ar.AsyncDelegate; 15int result = del.EndInvoke(iar); 16 Console.WriteLine("回调函数执行EndInvoke"); 17 Console.WriteLine("result:{0}", result); 18 Console.WriteLine("回调函数完成"); 19 } 2021staticvoid Main(string[] args) 22 { 23 MyDel del = Sum; 24//执行BeginInvoke方法后原始线程就不用管了,在自定义的回调函数(CallWhenDone)中执行EndInvoke方法25 IAsyncResult iar = del.BeginInvoke(3, 5, CallWhenDone, null); 26 Console.WriteLine("开启新线程,异步任务完成后执行回调函数"); 27//doSomething28 Console.WriteLine("回调执行不阻塞原始线程"); 29 Console.ReadKey(); 30 } 31 }
执行结果:
还有一些其他的异步编程模式如BackgroundWorker这里不再细说了。
原文:https://www.cnblogs.com/wyy1234/p/9178647.html
内容总结
以上是互联网集市为您收集整理的C#多线程和异步(三)——一些异步编程模式全部内容,希望文章能够帮你解决C#多线程和异步(三)——一些异步编程模式所遇到的程序开发问题。 如果觉得互联网集市技术教程内容还不错,欢迎将互联网集市网站推荐给程序员好友。
内容备注
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 gblab@vip.qq.com 举报,一经查实,本站将立刻删除。
内容手机端
扫描二维码推送至手机访问。