C# BeginInvoke實現異步編程

C# BeginInvoke實現異步編程-CSDN博客

https://blog.csdn.net/Nire_Yeyu/article/details/133203267

 

C# BeginInvoke實現異步編程
BeginInvoke實現異步編程的三種模式:

1.等待模式
在發起了異步方法以及做了一些其他處理之後,原始線程就中斷並且等異步方法完成之後再繼續;
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); //進程延時3S,延長執行時間
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); //定義委託變量,引用任務1
IAsyncResult iar = objTest.BeginInvoke(3,4,null,null); //異步調用
textBox_Result1.Text = "計算中...";

textBox_Result2.Text = Cal_Task2(5,6).ToString(); //同時可以並行其他任務

int result = objTest.EndInvoke(iar); //獲取異步執行結果
//委託類型的EndInvoke()方法:藉助IAsyncResult接口對象,不斷查詢異步調用是否結束。
//該方法知道被異步調用的方法所有的參數,所以,異步調用結束後,取出異步調用結果作爲返回值
textBox_Result1.Text = result.ToString();
}
}
}

 

2.輪詢模式
原始線程定期檢查發起的線程是否完成,如果沒有則可以繼續做一些其他事情;
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");

//繼續處理
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.回調模式
原始線程一直執行,無需等待或檢查發起的線程是否完成。在發起的線程中引用方法完成之後,發起的線程就會調用回調方法,由回調方法再調用EndInvoke之前處理異步方法的結果。
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表達式
//this.objMyCal = (num, ms) =>
//{
// System.Threading.Thread.Sleep(ms);
// return num * num;
//};
}

//【3】創建委託變量(因爲異步函數和回調函數都要用,所以定義成成員變量)
private MyCalculator objMyCal = null;

//【4】同時執行多個任務
private void btnExec_Click(object sender, EventArgs e)
{
//發佈任務
for (int i = 1; i < 11; i++)
{
//開始異步執行
objMyCal.BeginInvoke(10 * i, 1000 * i, MyCallBack, i);
//最後一個參數i給回調函數的字段AsyncState賦值,如果數據很多可以定義成類或結構
}
}

//【5】回調函數
private void MyCallBack(IAsyncResult result)
{
int res = objMyCal.EndInvoke(result);
//顯示異步調用結果:result.AsyncState字段用來封裝回調函數自定義參數,object類型
Console.WriteLine("第{0}個計算結果爲:{1}", result.AsyncState.ToString(), res);
}

//【2】根據委託定義一個方法:返回一個數的平方
private int ExecuteTask(int num, int ms)
{
System.Threading.Thread.Sleep(ms);
return num * num;
}

//【1】聲明委託
private delegate int MyCalculator(int num, int ms);
}
//異步編程的總結:
//1. 異步編程是建立在委託的基礎上一種編程的方法。
//2. 異步調用的每個方法都是在獨立的線程中執行的。因此,本質上就是一種多線程程序,是簡化的多線程。
//3. 比較適合在後臺運行較爲耗時的《簡單任務》,並且任務之間要求相互獨立,任務中不應該有直接訪問可視化控件大代碼。
//4. 如果後臺任務要求必須按照特定順序執行,或者訪問共享資源,則異步編程不太適合,應選擇多線程開發技術。
}

 

————————————————
版權聲明:本文爲CSDN博主「Danny_hi」的原創文章,遵循CC 4.0 BY-SA版權協議,轉載請附上原文出處鏈接及本聲明。
原文鏈接:https://blog.csdn.net/qq_43024228/article/details/98600254

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章