国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁(yè) > 學(xué)院 > 開(kāi)發(fā)設(shè)計(jì) > 正文

C#基礎(chǔ)---事件的使用

2019-11-14 16:21:28
字體:
來(lái)源:轉(zhuǎn)載
供稿:網(wǎng)友

   一:什么是事件

       事件是可以被控件識(shí)別的操作,如按下確定按鈕,選擇某個(gè)單選按鈕或者復(fù)選框。每一種控件有自己可以識(shí)別的事件,如窗體的加載、單擊、雙擊等事件,編輯框(文本框)的文本改變事件,等等。事件在桌面應(yīng)用程序里面無(wú)處可見(jiàn),比如winform,WPF。。。,其次事件是基于委托而產(chǎn)生的。

        二:事件的基本使用

     1.事件的聲明: 其實(shí)和委托一樣只是多了一個(gè)Event而已。ShowMsg 就具備了ShowMsgHandler的功能。

    Notes: 1. 委托可以依賴(lài)于一個(gè)類(lèi)或者一個(gè)域名空間(C#基礎(chǔ)---委托的使用,里面我有提到過(guò)), 而event必須依賴(lài)于一個(gè)類(lèi)。否者無(wú)法聲明。

         2. 委托可以用【=號(hào)】,而事件中只能用【+】或者【-】實(shí)現(xiàn)對(duì)方法的添加和刪除。當(dāng)事件為空的時(shí)候調(diào)用【-】方法不會(huì)報(bào)錯(cuò)。

        

public delegate void ShowMsgHandler(string str);public event ShowMsgHandler ShowMsg;

     2.事件基本使用: 其實(shí)基本用法和委托差不多。這里有一點(diǎn)要說(shuō)明,其實(shí)可以通過(guò)判斷是否為Null,來(lái)確定是否已經(jīng)注冊(cè)了方法到事件或者委托。這個(gè)有時(shí)候勇于判斷事件是否該觸發(fā)。其次也發(fā)現(xiàn)事件第一次添加方法的時(shí)候是直接使用【+】號(hào)的,而不用像委托那樣第一次使用【=】號(hào),后面的才使用【+】號(hào)。         

using System;using System.Collections.Generic;using System.Linq;using System.Text;using System.Threading.Tasks;namespace SpongeBobCoder.EventTest{    public delegate void ShowMsgHandler(string str);    public class PRogram    {        public static event ShowMsgHandler ShowMsg;        public static void ShowName(string str)        {            Console.WriteLine("My Name is {0}", str);        }        public static void Main(string[] args)        {            Console.WriteLine(ShowMsg == null);            ShowMsg += ShowName;            ShowMsg("SopongeBob");            Console.WriteLine(ShowMsg == null);            Console.ReadKey();        }    }}

      3. 為何使用事件:

             其實(shí)從上面來(lái)看事件和委托差不多。用法沒(méi)啥區(qū)別,但是為何還要使用委托呢? 在Codeplex看到的一篇文檔感覺(jué)挺不錯(cuò)的。http://www.codeproject.com/Articles/7316/Events-and-Delegates ;小弟英語(yǔ)不好,英語(yǔ)好的就去看看原文,我的大概理解是: 好比一個(gè)App由一個(gè)項(xiàng)目組在開(kāi)發(fā),必定有一個(gè)項(xiàng)目經(jīng)理,而這個(gè)項(xiàng)目經(jīng)理的下面會(huì)有很多幫他做事的員工,其實(shí)經(jīng)理就好比是一個(gè)委托,而每一位工作的員工就好比委托注冊(cè)的方法。項(xiàng)目開(kāi)發(fā)完成了,拿給了用戶(hù),用戶(hù)安裝好了。可是用戶(hù)發(fā)現(xiàn)軟件有缺陷,需要改進(jìn),而往往這個(gè)時(shí)候用戶(hù)是不會(huì)直接跟開(kāi)發(fā)組的項(xiàng)目經(jīng)理接觸的。往往會(huì)把意見(jiàn)給 維護(hù)部門(mén),而由維護(hù)部門(mén)來(lái)告知相應(yīng)開(kāi)發(fā)組的項(xiàng)目經(jīng)理。而通知這段過(guò)程就叫做事件。事件可以用來(lái)更好的封裝,和管理委托的。個(gè)人理解,這就是事件為何基于特定類(lèi)的。不同類(lèi)的 事件可以綁定同一個(gè)委托,從而注冊(cè)不同的方法。

       3.1 先什么一個(gè)Publisher類(lèi):類(lèi)中有一個(gè)事件CalculatorEvent 和一個(gè)方法DoSomething,若事件被添加方法后,那么將執(zhí)行

    

using System;using System.Collections.Generic;using System.Linq;using System.Text;using System.Threading.Tasks;namespace SpongeBobCoder.EventTest{    public class Publisher    {        public event CalculatorHandler CalculatorEvent;        public void DoSomething(double num1,double num2)        {            if (CalculatorEvent != null)            {                CalculatorEvent(num1, num2);            }        }    }}

    3.2 然后看Program類(lèi),Main方法里面聲明了兩個(gè)Publisher對(duì)象,分別是A,B。分別添加了AddNum和SumNum,運(yùn)行結(jié)果是 3 和 -1。通過(guò)一個(gè)Publisher類(lèi)可以對(duì)委托進(jìn)行管理。

using System;using System.Collections.Generic;using System.Linq;using System.Text;using System.Threading.Tasks;namespace SpongeBobCoder.EventTest{    public delegate void CalculatorHandler(double num1,double num2);    public class Program    {        public static void AddNum(double num1, double num2)        {            Console.WriteLine("兩數(shù)之和為:{0}", num1 + num2);        }        public static void SubNum(double num1, double num2)        {            Console.WriteLine("兩數(shù)之差為:{0}", num1-num2);        }        public static void Main(string[] args)        {            Publisher pubA = new Publisher();            Publisher pubB = new Publisher();            pubA.CalculatorEvent += AddNum;            pubB.CalculatorEvent += SubNum;            pubA.DoSomething(1, 2);            pubB.DoSomething(1, 2);            Console.ReadKey();        }    }}

     三:事件的使用

    1.異常處理: 事件可以注冊(cè)多個(gè)方法,可是要是其中有一個(gè)方法拋出異常了怎么辦,一旦拋出異常了。那么當(dāng)前執(zhí)行程序被中斷,那么后面注冊(cè)的方法就沒(méi)法執(zhí)行了。問(wèn)題來(lái)了,那些方法可以解決這個(gè)問(wèn)題呢?  方法一,保證所注冊(cè)的方法不會(huì)出現(xiàn)異常,這一塊我們是無(wú)法預(yù)知。 方法二。將注冊(cè)的方法的異常都吃掉,其中微軟提供了兩個(gè)方法GetInvocationList和DynamicInvoke方法:

using System;using System.Collections.Generic;using System.Linq;using System.Text;using System.Threading.Tasks;namespace SpongeBobCoder.EventTest{    public class Publisher    {        public event CalculatorHandler CalculatorEvent;        public void DoSomething(double num1, double num2)        {            if (CalculatorEvent != null)            {                Delegate[] delArray = CalculatorEvent.GetInvocationList(); //獲取到所有的委托方法.                foreach (Delegate del in delArray)                {                    try                    {                       object obj = del.DynamicInvoke(num1, num2); //obj是獲取每個(gè)方法的返回值,如果聲明的是無(wú)返回值的委托,那么obj==null                       Console.WriteLine(obj == null);                    }                    catch (Exception e) // 把異常吃掉                    {                        Console.WriteLine(e.InnerException.Message);                     }                }            }        }    }}

  2.異步調(diào)用:對(duì)于前面的注冊(cè)的時(shí)間,都是順序執(zhí)行,那如何實(shí)現(xiàn)異步執(zhí)行呢,各個(gè)注冊(cè)之間不相互干擾,其實(shí)微軟提供了一個(gè)BeginInvoke方法可以解決這個(gè)問(wèn)題.

Public IAsyncResult BeginInvoke (    InvokeArgs invokeArgs, // 這一部分對(duì)于的是委托    AsyncCallback callback,// 回調(diào)方法,注冊(cè)方法執(zhí)行完后,將會(huì)執(zhí)行回調(diào)方法    Object userState // 傳遞的參數(shù))

            上面理解起來(lái)可能有點(diǎn)困難下面來(lái)看看代碼吧:
            Program類(lèi): AddNum 方法有5秒的延時(shí)。SubNum沒(méi)有添加延時(shí),注冊(cè)順序是 AddNum,SubNum

using System;using System.Collections.Generic;using System.Linq;using System.Text;using System.Threading.Tasks;using System.Threading;namespace SpongeBobCoder.EventTest{    public delegate double CalculatorHandler(double num1, double num2);    public class Program    {        public static double AddNum(double num1, double num2)        {            Thread.Sleep(TimeSpan.FromSeconds(5));            Console.WriteLine("兩數(shù)之和為:{0}", num1 + num2);            return num1 + num2;        }        public static double SubNum(double num1, double num2)        {            Console.WriteLine("兩數(shù)之差為:{0}", num1 - num2);            return num1 - num2;        }        public static void Main(string[] args)        {            Publisher pubA = new Publisher();            pubA.CalculatorEvent += AddNum;            pubA.CalculatorEvent += SubNum;            pubA.DoSomething(1, 5);            Console.ReadKey();        }    }}

    publisher類(lèi): 注意看紅色方法,前面兩個(gè)參數(shù)是與委托對(duì)應(yīng)的。后面的MyCallBack是回調(diào)的方法,

using System;using System.Collections.Generic;using System.Linq;using System.Runtime.Remoting.Messaging;using System.Text;using System.Threading.Tasks;namespace SpongeBobCoder.EventTest{    public class Publisher    {        public event CalculatorHandler CalculatorEvent;        public void DoSomething(double num1, double num2)        {            if (CalculatorEvent != null)            {                Delegate[] delArray = CalculatorEvent.GetInvocationList(); //獲取到所有的委托方法.                foreach (Delegate del in delArray)                {                    try                    {                        CalculatorHandler handler = del as CalculatorHandler;                        IAsyncResult myResult = handler.BeginInvoke(num1, num2, MyCallback, "方法執(zhí)行完畢,回調(diào)成功" + handler.Method.Name);                        // Console.WriteLine("SpongeBob"); 這塊代碼不注釋的話是先執(zhí)行這段代碼的輸出,然后才會(huì)輸出其他的。這一塊我不知道為什么                    }                    catch (Exception e) // 把異常吃掉                    {                        Console.WriteLine(e.InnerException.Message);                    }                }            }        }        public void MyCallback(IAsyncResult asyncResult)        {            AsyncResult result = (AsyncResult)asyncResult;            CalculatorHandler handler = (CalculatorHandler)result.AsyncDelegate;            Console.WriteLine(asyncResult.AsyncState);            Console.WriteLine("獲取到執(zhí)行結(jié)果為:{0} /n", handler.EndInvoke(asyncResult));        }    }}

        運(yùn)行結(jié)果: 其實(shí)先執(zhí)行的是 SubNum,已經(jīng)達(dá)到了異步的效果,其中通過(guò)EndInvoke也在回調(diào)函數(shù)中獲取到了委托的返回值。
     

      codezip:http://files.VEVb.com/FourLeafCloverZc/CSharp.zip

總結(jié):  以前最開(kāi)始的對(duì)事件理解不清楚,記得當(dāng)時(shí)在winform的時(shí)候跨線程獲取數(shù)據(jù)就要用Invoke來(lái)獲取,不然老是提示線程不安全。本次博客中我發(fā)現(xiàn)了兩個(gè)問(wèn)題需要個(gè)各位博友幫忙解答

 1. 在異步調(diào)用的代碼中有一段代碼被我注解了。其實(shí)我發(fā)現(xiàn)了一個(gè)問(wèn)題, 如果 Console.WriteLine("SpongeBob"); 不注解,運(yùn)行的情況是,先輸出兩行(“SpongeBob”) 然后再輸出 上圖的運(yùn)行結(jié)果。不清楚是什么原因,求大神指點(diǎn)。

 2. 對(duì)于下面代碼如果調(diào)用的傳入的參數(shù)是1,0 ; 是不會(huì)報(bào)錯(cuò)的。運(yùn)行結(jié)果是兩數(shù)相除無(wú)窮大。應(yīng)該會(huì)報(bào)除數(shù)不能為0的異常呀。

        public static void DivNum(double num1, double num2)        {            Console.WriteLine("兩數(shù)相除為:{0}", num1 / num2);        }

 


發(fā)表評(píng)論 共有條評(píng)論
用戶(hù)名: 密碼:
驗(yàn)證碼: 匿名發(fā)表
主站蜘蛛池模板: 天峻县| 安塞县| 南乐县| 雅安市| 绵阳市| 新密市| 土默特左旗| 忻州市| 峨边| 宜兰县| 柘城县| 峨眉山市| 济宁市| 稻城县| 凤冈县| 比如县| 武定县| 喀喇| 阜新| 五峰| 罗定市| 辰溪县| 苍山县| 邯郸市| 城口县| 出国| 进贤县| 大竹县| 曲沃县| 南城县| 马关县| 昆明市| 无棣县| 若羌县| 彝良县| 崇文区| 佛冈县| 三原县| 堆龙德庆县| 民丰县| 长岛县|