超碰人人人人人,亚洲AV午夜福利精品一区二区,亚洲欧美综合区丁香五月1区,日韩欧美亚洲系列

LOGO OA教程 ERP教程 模切知識(shí)交流 PMS教程 CRM教程 開(kāi)發(fā)文檔 其他文檔  
 
網(wǎng)站管理員

C#委托的原理和案例

freeflydom
2024年12月11日 8:46 本文熱度 827

一、前言

十年前,剛開(kāi)始學(xué)C#編程的時(shí)候,被委托困擾了很久。

今天跟大家分享一下關(guān)于委托的那些事兒。

二、委托原理

什么是委托?

拋開(kāi)編程,委托是一個(gè)漢語(yǔ)詞語(yǔ),指的是把事情托付給別人或別的機(jī)構(gòu)辦理。

為什么會(huì)有委托?什么時(shí)候使用委托?

有些事情我們直接干不了,需要找人來(lái)幫忙。

比如:

我們需要在主窗體中刷新子窗體的控件,

我們需要在多線程中刷新主線程的控件。

我們需要在某個(gè)窗體中執(zhí)行另一個(gè)窗體的方法。

總之,當(dāng)我們直接完成不了的時(shí)候,就可以考慮使用委托,如果可以直接完成,就沒(méi)有委托什么事了。

三、委托案例

今天,我們結(jié)合一個(gè)案例來(lái)了解委托的前世今生。

這個(gè)錯(cuò)誤應(yīng)該每個(gè)人都遇到過(guò),代碼很簡(jiǎn)單,一運(yùn)行就報(bào)錯(cuò)。

我們來(lái)分析一下錯(cuò)誤提示:線程間操作無(wú)效:從不是創(chuàng)建控件“FrmMain”線程訪問(wèn)它。

這里的線程間意味著涉及兩個(gè)線程,一個(gè)就是我們開(kāi)的線程,另一個(gè)就是主線程。

從不是創(chuàng)建控件“FrmMain”線程,指的是什么線程呢?

我們知道程序運(yùn)行之后,就會(huì)有一個(gè)主線程,又叫UI線程,通常用于處理用戶界面相關(guān)的邏輯,如創(chuàng)建和顯示窗體、處理用戶輸入、更新UI等。

所以,創(chuàng)建控件"FrmMain"的線程就是主線程。

不是創(chuàng)建控件“FrmMain”線程指的就是我們開(kāi)的那個(gè)線程。

因此這個(gè)錯(cuò)誤的意思就是不能在多線程里直接訪問(wèn)主線程的控件。

這個(gè)我們做牛馬的應(yīng)該都能理解,比如你花了半個(gè)月寫了一個(gè)很牛的程序,你的同事想要"竊取",你是否愿意?

 

主線程辛辛苦苦創(chuàng)建了控件,多線程想直接給它賦值,主線程自然也不愿意,一怒之下,就給出了一個(gè)錯(cuò)誤警告。

四、解決方案

我們回到這個(gè)問(wèn)題上:你花了半個(gè)月寫了一個(gè)很牛的程序,你的同事想要"竊取",你不愿意給,他怎么辦呢?

于是,聰明的他開(kāi)始搬救兵,找到了你的領(lǐng)導(dǎo),表示他有一個(gè)類似的項(xiàng)目,利潤(rùn)很高,客戶很急,需要借用你的程序參考一下。

于是,你的領(lǐng)導(dǎo)跟你畫了一張餅,毋庸置疑,你同意了。

你的同事就是那個(gè)線程,而你就是主線程,你的領(lǐng)導(dǎo)就是委托。

我們?cè)倩氐竭@個(gè)錯(cuò)誤上來(lái),既然直接不能訪問(wèn)主線程的控件,那么就采用"委托"來(lái)實(shí)現(xiàn)。

想要使用委托,必然要先學(xué)會(huì)委托。

在C#中,委托是一種類型,它定義了方法的簽名,即方法的參數(shù)類型和返回值類型。

 

這句話如果沒(méi)看明白,就不用管它了。

我們先來(lái)看看如何使用委托,這里總結(jié)了委托的五步法:

1、聲明委托

聲明委托需要根據(jù)最終執(zhí)行方法來(lái)確定參數(shù)與返回值類型,然后根據(jù)參數(shù)和返回值來(lái)聲明。

我們目的是給lbl_Time控件賦值當(dāng)前時(shí)間,因此參數(shù)和返回值均為空。

聲明委托代碼如下

//【1】聲明委托
public delegate void SetTimeDelegate();

2、創(chuàng)建委托對(duì)象

委托是一種類型,就像類class一樣,我們都知道如果要?jiǎng)?chuàng)建某個(gè)類的對(duì)象的寫法,那么創(chuàng)建委托對(duì)象是一樣的。

創(chuàng)建委托對(duì)象代碼如下:

//【2】創(chuàng)建委托對(duì)象
private SetTimeDelegate setTime;

3、創(chuàng)建委托方法

委托對(duì)象就像領(lǐng)導(dǎo)一樣,它是不干活的,最終干活的還得是下面的牛馬。

因此我們需要編寫一個(gè)最終干活的方法,我們這個(gè)活很簡(jiǎn)單,所以委托方法也很簡(jiǎn)單。

創(chuàng)建委托方法代碼如下:

//【3】創(chuàng)建委托方法
private void setTimeMethod()
{
   this.lbl_Time.Text = DateTime.Now.ToString("HH:mm:ss");
}

4、委托綁定

領(lǐng)導(dǎo)有了,牛馬有了,如何將這兩者聯(lián)系起來(lái)呢?

我們需要進(jìn)行關(guān)系綁定,這就需要進(jìn)行委托綁定。

委托綁定代碼如下:

//【4】委托綁定
this.setTime = this.setTimeMethod;

5、委托調(diào)用

如果不涉及多線程,直接就像調(diào)用方法一樣調(diào)用委托對(duì)象即可。

但是這里涉及到了多線程,也就是我們這里最終仍然需要主線程來(lái)調(diào)用。

怎么通過(guò)主線程來(lái)調(diào)用這個(gè)委托對(duì)象呢?

Control類中提供了一個(gè)Invoke方法,這個(gè)方法的含義是在擁有此控件的基礎(chǔ)窗體句柄的線程上執(zhí)行指定的委托。

委托調(diào)用的代碼如下:

//多線程方法
private void TaskMethod()
{
   //【5】調(diào)用委托
   this.lbl_Time.Invoke(setTime);
}

這樣就基于委托解決了跨線程訪問(wèn)的問(wèn)題。

我們運(yùn)行一下程序,效果如下:

這時(shí)候,我們?cè)诳催@句話,是不是就豁然開(kāi)朗了呢?

委托是一種類型,它定義了方法的簽名,即方法的參數(shù)類型和返回值類型。

如果我們接觸過(guò)C++編程,委托類似于C++中的指針。

 

五、委托今生

.Net Framework3.5之后開(kāi)始有了Action和Func,Action和Func是內(nèi)置委托,也叫系統(tǒng)委托,就是微軟的工程師幫我們?cè)诘讓訉懞昧宋新暶?,這樣我們就不需要聲明委托。

Action委托針對(duì)無(wú)返回值情況,具有Action、Action<T>、Action<T1,T2>、Action<T1,T2,T3>……Action<T1,……T16>多達(dá)16個(gè)參數(shù)的形式,其中傳入?yún)?shù)均采用泛型T,涵蓋了幾乎所有可能存在的無(wú)返回值的委托類型。

Func委托針對(duì)有返回值情況,具有Func<TResult>、Func<T,Tresult>……Func<T1,T2,T3……,Tresult>17種類型重載,T1……T16為參數(shù),Tresult為返回類型。

于是我們開(kāi)始簡(jiǎn)化我們的代碼:

第一步簡(jiǎn)化:使用Action,不需要聲明委托,創(chuàng)建的時(shí)候直接綁定

 //多線程方法
  private void TaskMethod()
  {
      //創(chuàng)建并綁定
      Action action = new Action(setTimeMethod);
      //調(diào)用委托
      this.lbl_Time.Invoke(action);
  }

第二步簡(jiǎn)化:action對(duì)象只使用一次,直接調(diào)用即可

   //多線程方法
   private void TaskMethod()
   {
       //創(chuàng)建委托、綁定委托、調(diào)用委托
       this.lbl_Time.Invoke(new Action(setTimeMethod));
   }

第三步簡(jiǎn)化:使用Lambda表達(dá)式替換委托方法

//多線程方法
private void TaskMethod()
{
    //創(chuàng)建委托、委托方法、綁定委托、調(diào)用委托
    this.lbl_Time.Invoke(new Action(()=>
    {
        this.lbl_Time.Text = DateTime.Now.ToString("HH:mm:ss");
    }));
}

這個(gè)最終簡(jiǎn)化的代碼是不是非常熟悉呢?

轉(zhuǎn)自https://www.cnblogs.com/xiketangedu/p/18594690


該文章在 2024/12/11 8:46:31 編輯過(guò)
關(guān)鍵字查詢
相關(guān)文章
正在查詢...
點(diǎn)晴ERP是一款針對(duì)中小制造業(yè)的專業(yè)生產(chǎn)管理軟件系統(tǒng),系統(tǒng)成熟度和易用性得到了國(guó)內(nèi)大量中小企業(yè)的青睞。
點(diǎn)晴PMS碼頭管理系統(tǒng)主要針對(duì)港口碼頭集裝箱與散貨日常運(yùn)作、調(diào)度、堆場(chǎng)、車隊(duì)、財(cái)務(wù)費(fèi)用、相關(guān)報(bào)表等業(yè)務(wù)管理,結(jié)合碼頭的業(yè)務(wù)特點(diǎn),圍繞調(diào)度、堆場(chǎng)作業(yè)而開(kāi)發(fā)的。集技術(shù)的先進(jìn)性、管理的有效性于一體,是物流碼頭及其他港口類企業(yè)的高效ERP管理信息系統(tǒng)。
點(diǎn)晴WMS倉(cāng)儲(chǔ)管理系統(tǒng)提供了貨物產(chǎn)品管理,銷售管理,采購(gòu)管理,倉(cāng)儲(chǔ)管理,倉(cāng)庫(kù)管理,保質(zhì)期管理,貨位管理,庫(kù)位管理,生產(chǎn)管理,WMS管理系統(tǒng),標(biāo)簽打印,條形碼,二維碼管理,批號(hào)管理軟件。
點(diǎn)晴免費(fèi)OA是一款軟件和通用服務(wù)都免費(fèi),不限功能、不限時(shí)間、不限用戶的免費(fèi)OA協(xié)同辦公管理系統(tǒng)。
Copyright 2010-2025 ClickSun All Rights Reserved