亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb

首頁 > 學院 > 開發設計 > 正文

C#基礎---事件的使用

2019-11-14 16:21:28
字體:
來源:轉載
供稿:網友

   一:什么是事件

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

        二:事件的基本使用

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

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

         2. 委托可以用【=號】,而事件中只能用【+】或者【-】實現對方法的添加和刪除。當事件為空的時候調用【-】方法不會報錯。

        

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

     2.事件基本使用: 其實基本用法和委托差不多。這里有一點要說明,其實可以通過判斷是否為Null,來確定是否已經注冊了方法到事件或者委托。這個有時候勇于判斷事件是否該觸發。其次也發現事件第一次添加方法的時候是直接使用【+】號的,而不用像委托那樣第一次使用【=】號,后面的才使用【+】號?!     ?nbsp;  

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. 為何使用事件:

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

       3.1 先什么一個Publisher類:類中有一個事件CalculatorEvent 和一個方法DoSomething,若事件被添加方法后,那么將執行

    

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類,Main方法里面聲明了兩個Publisher對象,分別是A,B。分別添加了AddNum和SumNum,運行結果是 3 和 -1。通過一個Publisher類可以對委托進行管理。

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("兩數之和為:{0}", num1 + num2);        }        public static void SubNum(double num1, double num2)        {            Console.WriteLine("兩數之差為:{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.異常處理: 事件可以注冊多個方法,可是要是其中有一個方法拋出異常了怎么辦,一旦拋出異常了。那么當前執行程序被中斷,那么后面注冊的方法就沒法執行了。問題來了,那些方法可以解決這個問題呢?  方法一,保證所注冊的方法不會出現異常,這一塊我們是無法預知。 方法二。將注冊的方法的異常都吃掉,其中微軟提供了兩個方法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是獲取每個方法的返回值,如果聲明的是無返回值的委托,那么obj==null                       Console.WriteLine(obj == null);                    }                    catch (Exception e) // 把異常吃掉                    {                        Console.WriteLine(e.InnerException.Message);                     }                }            }        }    }}

  2.異步調用:對于前面的注冊的時間,都是順序執行,那如何實現異步執行呢,各個注冊之間不相互干擾,其實微軟提供了一個BeginInvoke方法可以解決這個問題.

Public IAsyncResult BeginInvoke (    InvokeArgs invokeArgs, // 這一部分對于的是委托    AsyncCallback callback,// 回調方法,注冊方法執行完后,將會執行回調方法    Object userState // 傳遞的參數)

            上面理解起來可能有點困難下面來看看代碼吧:
            Program類: AddNum 方法有5秒的延時。SubNum沒有添加延時,注冊順序是 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("兩數之和為:{0}", num1 + num2);            return num1 + num2;        }        public static double SubNum(double num1, double num2)        {            Console.WriteLine("兩數之差為:{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類: 注意看紅色方法,前面兩個參數是與委托對應的。后面的MyCallBack是回調的方法,

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, "方法執行完畢,回調成功" + handler.Method.Name);                        // Console.WriteLine("SpongeBob"); 這塊代碼不注釋的話是先執行這段代碼的輸出,然后才會輸出其他的。這一塊我不知道為什么                    }                    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("獲取到執行結果為:{0} /n", handler.EndInvoke(asyncResult));        }    }}

        運行結果: 其實先執行的是 SubNum,已經達到了異步的效果,其中通過EndInvoke也在回調函數中獲取到了委托的返回值。
     

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

總結:  以前最開始的對事件理解不清楚,記得當時在winform的時候跨線程獲取數據就要用Invoke來獲取,不然老是提示線程不安全。本次博客中我發現了兩個問題需要個各位博友幫忙解答

 1. 在異步調用的代碼中有一段代碼被我注解了。其實我發現了一個問題, 如果 Console.WriteLine("SpongeBob"); 不注解,運行的情況是,先輸出兩行(“SpongeBob”) 然后再輸出 上圖的運行結果。不清楚是什么原因,求大神指點。

 2. 對于下面代碼如果調用的傳入的參數是1,0 ; 是不會報錯的。運行結果是兩數相除無窮大。應該會報除數不能為0的異常呀。

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

 


發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb
91精品视频网站| www高清在线视频日韩欧美| 欧美精品制服第一页| 久久精品久久久久电影| 日韩av在线一区二区| 亚洲欧美中文字幕在线一区| 国产97在线视频| 亚洲男子天堂网| 精品伊人久久97| 欧美专区福利在线| 三级精品视频久久久久| 奇米一区二区三区四区久久| 亚洲成人久久一区| 亚洲视频在线视频| 欧美亚洲国产精品| 久久99精品久久久久久青青91| 中文综合在线观看| 最近中文字幕mv在线一区二区三区四区| 色悠悠久久久久| 精品少妇一区二区30p| 欧美一性一乱一交一视频| 国产日韩中文字幕| 亚洲一级黄色片| 国产精品视频999| 国产一区红桃视频| 成人乱人伦精品视频在线观看| 久久久久国色av免费观看性色| 欧美激情综合亚洲一二区| 一区二区三区视频免费在线观看| 国产成人精品一区| 热久久这里只有| 日韩天堂在线视频| 欧美精品久久久久久久免费观看| 欧美夫妻性生活视频| 亚洲午夜未删减在线观看| 夜夜躁日日躁狠狠久久88av| www.久久撸.com| 国产精品久久久久免费a∨大胸| 久久久久久有精品国产| 成人激情电影一区二区| 亚洲欧美激情在线视频| 日韩精品视频免费在线观看| 福利视频第一区| 国产精品一区二区3区| 国产精品日韩在线播放| 欧美极度另类性三渗透| 国产一区二区三区毛片| 国产日韩精品入口| 国产一区二区三区视频在线观看| 日韩在线中文字幕| 日韩成人在线观看| 中文字幕日韩精品在线观看| 亚洲日本aⅴ片在线观看香蕉| 亚洲老板91色精品久久| 国产精品高潮呻吟久久av黑人| 91香蕉嫩草影院入口| 欧美日韩国产一中文字不卡| 精品久久在线播放| 伊人亚洲福利一区二区三区| 91国内免费在线视频| 久久国产精品首页| 欧美精品18videosex性欧美| 欧美日韩加勒比精品一区| 午夜精品福利在线观看| 亚洲欧美日韩第一区| 51午夜精品视频| 国产精品av网站| 亚洲欧美日韩国产中文| 久久久久久久久久久久av| 日韩成人中文字幕| 欧美日韩成人在线视频| 亚洲成人黄色在线观看| 亚洲欧洲偷拍精品| 国产日韩在线播放| 国产精品免费一区二区三区都可以| 日韩中文字幕视频在线观看| 欧美成人免费播放| 亚洲qvod图片区电影| 深夜精品寂寞黄网站在线观看| 91精品国产91久久久| 97激碰免费视频| 精品久久久久久久久久国产| 国产精品久久久久久久天堂| 久久久久99精品久久久久| 亚洲小视频在线观看| 孩xxxx性bbbb欧美| 亚洲另类图片色| 日韩的一区二区| 久久久久久美女| 日韩欧亚中文在线| 久久香蕉国产线看观看av| 久久人人爽亚洲精品天堂| 精品国产一区二区三区久久久狼| 色哟哟网站入口亚洲精品| 亚洲国产一区二区三区在线观看| 国产精品一区二区三区久久久| 欧美老女人在线视频| 性亚洲最疯狂xxxx高清| 国产精品丝袜白浆摸在线| www.久久久久| 91老司机精品视频| 在线观看久久av| 日韩欧美国产高清91| 国产精品视频网址| 欧美日韩在线视频首页| 91免费综合在线| 久久久久久午夜| 久久久久久久国产| 日韩av在线天堂网| 亚洲色图15p| 国产精品久久久久久五月尺| 亚洲精品大尺度| 91高潮在线观看| 亚洲欧美综合精品久久成人| 日韩欧美一区二区三区久久| 亚洲国产成人精品久久久国产成人一区| 欧美精品手机在线| 亚洲精品小视频| 国内伊人久久久久久网站视频| 成人免费看片视频| 自拍偷拍免费精品| 久青草国产97香蕉在线视频| 中文字幕日韩高清| 国产精品aaaa| 日韩av免费在线| www.久久草.com| 亚洲欧洲xxxx| 成人有码在线视频| 久久黄色av网站| 欧美日韩国产成人在线| 国产视频在线观看一区二区| 中文字幕亚洲在线| 亚洲欧美在线第一页| 欧美日韩亚洲精品一区二区三区| 亚洲电影免费观看高清完整版| 国产成人精品在线播放| 国产成人精品一区二区三区| 最新国产成人av网站网址麻豆| 热久久免费视频精品| 久久97精品久久久久久久不卡| 久久久精品一区二区三区| 亚洲欧洲日产国码av系列天堂| 日产精品久久久一区二区福利| 九九热这里只有在线精品视| 亚洲 日韩 国产第一| 国产在线a不卡| 国产精品第3页| 日韩在线国产精品| 欧美怡春院一区二区三区| 日韩av中文字幕在线免费观看| 中文字幕久久久av一区| 精品久久久91| 北条麻妃在线一区二区| 国产成人精品在线视频| 色综合五月天导航| 欧美国产日韩xxxxx| 欧美有码在线视频| xxxxx91麻豆| 亚洲国产第一页| 国产精品视频精品| 欧美另类暴力丝袜| 97视频在线看| 国产成人亚洲综合| 欧美自拍视频在线|