委託非同步呼叫時BeginInvoke的陷阱處理

2022-03-03 06:21:26 字數 1880 閱讀 3488

這個陷阱來自於乙個需求:需要非同步在後台處理資料,處理完後觸發處理完成的事件,大概是這麼寫的:

employeecollection data = new

employeecollection();

data.loaded +=data_loaded;

action

action = (d) =>;

action.begininvoke(data,

null, null);

挺簡單的**,陷阱也在其中。假如dalhelper.fill(data)丟擲了乙個異常,那麼對data.raiseeventloaded()就不會執行,依賴於data.loaded事件的**也不會執行,這是乙個bug,應該在委託執行中加入乙個try...catch語句,或者在某個地方呼叫委託的endinvoke方法,來處理執行中可能的異常。

為了這麼乙個簡單的需求,加入try...catch或者呼叫委託的endinvoke都太複雜了,僅僅只想滿足假如執行失敗,就把異常丟擲來,即使將當前程序結束也沒事。本著一次編寫,多次使用的原則,專門設計了乙個幫助類來專職這類委託的非同步呼叫。幫助類的**如下:

public

class

eventhelper

delegate

void asyncfire(delegate del,object

args);

static

void invokedelegate(delegate del,object

args)

static

void

throwcallback(iasyncresult ar)

}

核心實現是將委託的呼叫封裝起來,在另外乙個委託中去呼叫,然後對另外的那個委託用endinvoke來釋放可能的異常,這樣就能夠發現單純的呼叫begininvoke後委託執行時引發的異常。這樣修改後,剛才的**就可以這樣來呼叫:

employeecollection data = new

employeecollection();

data.loaded +=data_loaded;

action

action = (d) =>;

eventhelper.unsafebegininvoke(action, data);

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

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

public

class

eventhelper

delegate

void asyncfire(delegate del,object

args);

static

void invokedelegate(delegate del,object

args)

static

void

throwcallback(iasyncresult ar)

#region 新增型別安全的委託

public

static

void

begininvoke(action del)

public

static

void begininvoke(actiondel,t t, u u)

public

static

void begininvoke(actiondel,t t, u u, v v)

#endregion 新增型別安全的委託}

view code

各位同學可以根據自己的需要新增型別安全的實現。

C 委託非同步呼叫

廢話不多說,直接上 ps 我就喜歡簡單 直接 粗暴 using system using system.collections.generic using system.linq using system.runtime.remoting.messaging using system.text us...

執行緒 委託的非同步呼叫

c programming p323 begininvoke 會立即返回,它將建立乙個另乙個執行緒來完成自己的工作。當我需要它執行後的結果時 例如 pubilc delegate in testdetegate pubilc testdetegate thedetegate thedetegate ...

C 委託的非同步呼叫

本文將主要通過 同步呼叫 非同步呼叫 非同步 三個示例來講解在用委託執行同乙個 加法類 的時候的的區別和利弊。首先,通過 定義乙個委託和下面三個示例將要呼叫的方法 新增的命名空間 using system.threading using system.runtime.remoting.messagi...