C# BeginInvoke實(shí)現(xiàn)異步編程方式
BeginInvoke實(shí)現(xiàn)異步編程的三種模式:
1.等待模式
在發(fā)起了異步方法以及做了一些其他處理之后,原始線程就中斷并且等異步方法完成之后再繼續(xù);
eg:
using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Linq; using System.Text; using System.Threading; using System.Threading.Tasks; using System.Windows.Forms;namespace BeginInvokeDemo { public delegate int myDelegate(int num1,int num2); //聲明委托 public partial class Form1 : Form { public Form1() { InitializeComponent(); } private int Cal_Task1(int num1, int num2) //方法一 { Thread.Sleep(3000); //進(jìn)程延時(shí)3S,延長(zhǎng)執(zhí)行時(shí)間 return num1 + num2; } private int Cal_Task2(int num1, int num2) //方法二 { return num1 + num2; } private void button_Calculate_Click(object sender, EventArgs e) { myDelegate objTest = new myDelegate(Cal_Task1); //定義委托變量,引用任務(wù)1 IAsyncResult iar = objTest.BeginInvoke(3,4,null,null); //異步調(diào)用 textBox_Result1.Text = "計(jì)算中..."; textBox_Result2.Text = Cal_Task2(5,6).ToString(); //同時(shí)可以并行其他任務(wù) int result = objTest.EndInvoke(iar); //獲取異步執(zhí)行結(jié)果 //委托類型的EndInvoke()方法:借助IAsyncResult接口對(duì)象,不斷查詢異步調(diào)用是否結(jié)束。 //該方法知道被異步調(diào)用的方法所有的參數(shù),所以,異步調(diào)用結(jié)束后,取出異步調(diào)用結(jié)果作為返回值 textBox_Result1.Text = result.ToString(); } } }
2.輪詢模式
原始線程定期檢查發(fā)起的線程是否完成,如果沒有則可以繼續(xù)做一些其他事情;
eg:
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading; using System.Threading.Tasks;namespace ConsoleApplication2 { delegate int MyDel(int num1,int num2); class Program { static void Main(string[] args) { MyDel del = new MyDel(Sum); IAsyncResult iar = del.BeginInvoke(3,4,null,null); Console.WriteLine("After BeginInvoke"); while(!iar.IsCompleted) { Console.WriteLine("Not Done"); //繼續(xù)處理 for (long i = 0; i < 10000000; i++) ; //空語句 } Console.WriteLine("Done"); int result = del.EndInvoke(iar); Console.WriteLine("Result:{0}",result); Console.ReadLine(); } static int Sum(int x,int y) { Console.WriteLine(" Inside Sum"); Thread.Sleep(100); return x + y; } } }
3.回調(diào)模式
原始線程一直執(zhí)行,無需等待或檢查發(fā)起的線程是否完成。
在發(fā)起的線程中引用方法完成之后,發(fā)起的線程就會(huì)調(diào)用回調(diào)方法,由回調(diào)方法再調(diào)用EndInvoke之前處理異步方法的結(jié)果。
eg:
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 _02_AsyncCallBackDemo { public partial class FrmCalllBack : Form { public FrmCalllBack() { InitializeComponent(); //【3】初始化委托變量 this.objMyCal = new MyCalculator(ExecuteTask); //也可以直接使用Lambda表達(dá)式 //this.objMyCal = (num, ms) => //{ // System.Threading.Thread.Sleep(ms); // return num * num; //}; } //【3】創(chuàng)建委托變量(因?yàn)楫惒胶瘮?shù)和回調(diào)函數(shù)都要用,所以定義成成員變量) private MyCalculator objMyCal = null; //【4】同時(shí)執(zhí)行多個(gè)任務(wù) private void btnExec_Click(object sender, EventArgs e) { //發(fā)布任務(wù) for (int i = 1; i < 11; i++) { //開始異步執(zhí)行 objMyCal.BeginInvoke(10 * i, 1000 * i, MyCallBack, i); //最后一個(gè)參數(shù)i給回調(diào)函數(shù)的字段AsyncState賦值,如果數(shù)據(jù)很多可以定義成類或結(jié)構(gòu) } } //【5】回調(diào)函數(shù) private void MyCallBack(IAsyncResult result) { int res = objMyCal.EndInvoke(result); //顯示異步調(diào)用結(jié)果:result.AsyncState字段用來封裝回調(diào)函數(shù)自定義參數(shù),object類型 Console.WriteLine("第{0}個(gè)計(jì)算結(jié)果為:{1}", result.AsyncState.ToString(), res); } //【2】根據(jù)委托定義一個(gè)方法:返回一個(gè)數(shù)的平方 private int ExecuteTask(int num, int ms) { System.Threading.Thread.Sleep(ms); return num * num; } //【1】聲明委托 private delegate int MyCalculator(int num, int ms); } //異步編程的總結(jié): //1. 異步編程是建立在委托的基礎(chǔ)上一種編程的方法。 //2. 異步調(diào)用的每個(gè)方法都是在獨(dú)立的線程中執(zhí)行的。因此,本質(zhì)上就是一種多線程程序,是簡(jiǎn)化的多線程。 //3. 比較適合在后臺(tái)運(yùn)行較為耗時(shí)的《簡(jiǎn)單任務(wù)》,并且任務(wù)之間要求相互獨(dú)立,任務(wù)中不應(yīng)該有直接訪問可視化控件大代碼。 //4. 如果后臺(tái)任務(wù)要求必須按照特定順序執(zhí)行,或者訪問共享資源,則異步編程不太適合,應(yīng)選擇多線程開發(fā)技術(shù)。 }
總結(jié)
以上為個(gè)人經(jīng)驗(yàn),希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。
相關(guān)文章
C#實(shí)現(xiàn)合并多張圖片為GIF動(dòng)態(tài)圖
這篇文章主要為大家詳細(xì)介紹了C#如何將把一張又一張的圖片去拼合成一張GIF動(dòng)態(tài)圖片,文中的示例代碼講解詳細(xì),感興趣的小伙伴可以了解一下2022-12-12C#集合根據(jù)對(duì)象的某個(gè)屬性進(jìn)行去重的代碼示例
當(dāng)根據(jù)對(duì)象的Name屬性進(jìn)行去重時(shí),你可以使用以下三種方法:使用Distinct方法和自定義比較器、使用LINQ的GroupBy方法,以及使用HashSet,下面給大家介紹C#集合根據(jù)對(duì)象的某個(gè)屬性進(jìn)行去重的代碼示例,感興趣的朋友一起看看吧2024-03-03C#實(shí)現(xiàn)仿QQ抽屜式窗體的設(shè)計(jì)方法
QQ軟件對(duì)于絕大多數(shù)的人來說再熟悉不過了,它以使用方便、界面美觀及功能完善而著稱,本文給大家介紹了C#實(shí)現(xiàn)仿QQ抽屜式窗體的設(shè)計(jì)方法,主要通過使用API函數(shù)WindowFromPoint和GetParent實(shí)現(xiàn)仿QQ的抽屜式窗體,需要的朋友可以參考下2024-04-04