欧美成人精品手机在线观看_69视频国产_动漫精品第一页_日韩中文字幕网 - 日本欧美一区二区

LOGO OA教程 ERP教程 模切知識交流 PMS教程 CRM教程 開發文檔 其他文檔  
 
網站管理員

C#委托的原理和案例

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

一、前言

十年前,剛開始學C#編程的時候,被委托困擾了很久。

今天跟大家分享一下關于委托的那些事兒。

二、委托原理

什么是委托?

拋開編程,委托是一個漢語詞語,指的是把事情托付給別人或別的機構辦理。

為什么會有委托?什么時候使用委托?

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

比如:

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

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

我們需要在某個窗體中執行另一個窗體的方法。

總之,當我們直接完成不了的時候,就可以考慮使用委托,如果可以直接完成,就沒有委托什么事了。

三、委托案例

今天,我們結合一個案例來了解委托的前世今生。

這個錯誤應該每個人都遇到過,代碼很簡單,一運行就報錯。

我們來分析一下錯誤提示:線程間操作無效:從不是創建控件“FrmMain”線程訪問它。

這里的線程間意味著涉及兩個線程,一個就是我們開的線程,另一個就是主線程。

從不是創建控件“FrmMain”線程,指的是什么線程呢?

我們知道程序運行之后,就會有一個主線程,又叫UI線程,通常用于處理用戶界面相關的邏輯,如創建和顯示窗體、處理用戶輸入、更新UI等。

所以,創建控件"FrmMain"的線程就是主線程。

不是創建控件“FrmMain”線程指的就是我們開的那個線程。

因此這個錯誤的意思就是不能在多線程里直接訪問主線程的控件。

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

 

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

四、解決方案

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

于是,聰明的他開始搬救兵,找到了你的領導,表示他有一個類似的項目,利潤很高,客戶很急,需要借用你的程序參考一下。

于是,你的領導跟你畫了一張餅,毋庸置疑,你同意了。

你的同事就是那個線程,而你就是主線程,你的領導就是委托。

我們再回到這個錯誤上來,既然直接不能訪問主線程的控件,那么就采用"委托"來實現。

想要使用委托,必然要先學會委托。

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

 

這句話如果沒看明白,就不用管它了。

我們先來看看如何使用委托,這里總結了委托的五步法:

1、聲明委托

聲明委托需要根據最終執行方法來確定參數與返回值類型,然后根據參數和返回值來聲明。

我們目的是給lbl_Time控件賦值當前時間,因此參數和返回值均為空。

聲明委托代碼如下

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

2、創建委托對象

委托是一種類型,就像類class一樣,我們都知道如果要創建某個類的對象的寫法,那么創建委托對象是一樣的。

創建委托對象代碼如下:

//【2】創建委托對象
private SetTimeDelegate setTime;

3、創建委托方法

委托對象就像領導一樣,它是不干活的,最終干活的還得是下面的牛馬。

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

創建委托方法代碼如下:

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

4、委托綁定

領導有了,牛馬有了,如何將這兩者聯系起來呢?

我們需要進行關系綁定,這就需要進行委托綁定。

委托綁定代碼如下:

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

5、委托調用

如果不涉及多線程,直接就像調用方法一樣調用委托對象即可。

但是這里涉及到了多線程,也就是我們這里最終仍然需要主線程來調用。

怎么通過主線程來調用這個委托對象呢?

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

委托調用的代碼如下:

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

這樣就基于委托解決了跨線程訪問的問題。

我們運行一下程序,效果如下:

這時候,我們在看這句話,是不是就豁然開朗了呢?

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

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

 

五、委托今生

.Net Framework3.5之后開始有了Action和Func,Action和Func是內置委托,也叫系統委托,就是微軟的工程師幫我們在底層寫好了委托聲明,這樣我們就不需要聲明委托。

Action委托針對無返回值情況,具有Action、Action<T>、Action<T1,T2>、Action<T1,T2,T3>……Action<T1,……T16>多達16個參數的形式,其中傳入參數均采用泛型T,涵蓋了幾乎所有可能存在的無返回值的委托類型。

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

于是我們開始簡化我們的代碼:

第一步簡化:使用Action,不需要聲明委托,創建的時候直接綁定

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

第二步簡化:action對象只使用一次,直接調用即可

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

第三步簡化:使用Lambda表達式替換委托方法

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

這個最終簡化的代碼是不是非常熟悉呢?

轉自https://www.cnblogs.com/xiketangedu/p/18594690


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