麻豆小视频在线观看_中文黄色一级片_久久久成人精品_成片免费观看视频大全_午夜精品久久久久久久99热浪潮_成人一区二区三区四区

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

委托異步調用時BeginInvoke的陷阱處理

2019-11-17 03:13:40
字體:
來源:轉載
供稿:網友

委托異步調用時BeginInvoke的陷阱處理

這個陷阱來自于一個需求:需要異步在后臺處理數據,處理完后觸發處理完成的事件,大概是這么寫的:

EmployeeCollection data = new EmployeeCollection();data.Loaded += data_Loaded;Action<EmployeeCollection> action = (d) => {    DalHelper.Fill(data);    data.RaiseEventLoaded();};action.BeginInvoke(data, null, null);

挺簡單的代碼,陷阱也在其中。假如DalHelper.Fill(data)拋出了一個異常,那么對data.RaiseEventLoaded()就不會執行,依賴于data.Loaded事件的代碼也不會執行,這是一個bug,應該在委托執行中加入一個try...catch語句,或者在某個地方調用委托的EndInvoke方法,來處理執行中可能的異常。

為了這么一個簡單的需求,加入try...catch或者調用委托的EndInvoke都太復雜了,僅僅只想滿足假如執行失敗,就把異常拋出來,即使將當前進程結束也沒事。本著一次編寫,多次使用的原則,專門設計了一個幫助類來專職這類委托的異步調用。幫助類的代碼如下:

public class EventHelper {   public static void UnsafeBeginInvoke(Delegate del,params object[] args){      AsyncFire asyncFire = InvokeDelegate;      asyncFire.BeginInvoke(del, args, ThrowCallback, asyncFire);   }         delegate void AsyncFire(Delegate del,object[] args);    static void InvokeDelegate(Delegate del,object[] args){        del.DynamicInvoke(args);    }   static void ThrowCallback(IAsyncResult ar) {        AsyncFire asyncFire = ar.AsyncState as AsyncFire;       asyncFire.EndInvoke(ar);   }}

核心實現是將委托的調用封裝起來,在另外一個委托中去調用,然后對另外的那個委托用EndInvoke來釋放可能的異常,這樣就能夠發現單純的調用BeginInvoke后委托執行時引發的異常。這樣修改后,剛才的代碼就可以這樣來調用:

EmployeeCollection data = new EmployeeCollection();data.Loaded += data_Loaded;Action<EmployeeCollection> action = (d) => {    DalHelper.Fill(data);    data.RaiseEventLoaded();};EventHelper.UnsafeBeginInvoke(action, data);

代碼還如最初的設計那么簡單,而且真要是委托中發生了異常,也能夠發現這個錯誤,而不是讓這個錯誤被掩蓋。

另外,剛才的實現不是類型安全的,類型安全可以通過重載來解決,例子如下:

public class EventHelper {   public static void UnsafeBeginInvoke(Delegate del,params object[] args){      AsyncFire asyncFire = InvokeDelegate;      asyncFire.BeginInvoke(del, args, ThrowCallback, asyncFire);   }         delegate void AsyncFire(Delegate del,object[] args);    static void InvokeDelegate(Delegate del,object[] args){        del.DynamicInvoke(args);    }   static void ThrowCallback(IAsyncResult ar) {        AsyncFire asyncFire = ar.AsyncState as AsyncFire;       asyncFire.EndInvoke(ar);   }   #region 添加類型安全的委托   public static void BeginInvoke(Action del){      UnsafeBeginInvoke(del);   }   public static void BeginInvoke<T,U>(Action<T,U> del,T t, U u){      UnsafeBeginInvoke(del,t,u);   }   public static void BeginInvoke<T,U,V>(Action<T,U> del,T t, U u, V v){      UnsafeBeginInvoke(del,t,u,v);   }   #endregion 添加類型安全的委托}
View Code

各位同學可以根據自己的需要添加類型安全的實現。


發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 国产精品视频六区 | 久久精品日韩一区 | 精品久久久久久久久久久久久 | 日本精品免费观看 | 欧美日韩在线免费观看 | 午夜视频久久 | 欧美精品色精品一区二区三区 | 欧美一级毛片美99毛片 | 蜜桃欧美性大片免费视频 | 91九色视频观看 | 国产精品成人一区二区三区电影毛片 | 黄色大片在线免费看 | 久久国产一 | 久久丝袜脚交足黄网站免费 | av不卡免费在线 | 久国产精品视频 | 国产流白浆高潮在线观看 | 日韩中文字幕三区 | 欧美久久久一区二区三区 | 99激情视频 | 日本在线视频免费观看 | 人禽l交免费视频观看 视频 | 黄污网址| 久久久日韩精品一区二区三区 | 亚洲视频网 | 91精品国产乱码久久桃 | 亚洲精品一区二区三区大胸 | 一级视频网站 | 国产一区网址 | 免费看日韩av | 成人毛片网 | 日本aaaa片毛片免费观蜜桃 | 欧美日韩精品一区二区三区不卡 | 国产日韩免费观看 | 红杏网站永久免费视频入口 | 成人综合区一区 | 国产精品一区二区三区在线播放 | 黄色网址在线免费播放 | av免费在线观看免费 | 国产91av视频 | 最新av网址在线观看 |