當編寫使用的BeginInvoke/EndInvoke會模式異步方法實現的代碼可能看起來像以下(和拯救你猜測這是圍繞一個緩存異步包裝):結束與部分類型信息異步委託調用
IAsyncResult BeginPut(string key, object value)
{
Action<string, object> put = this.cache.Put;
return put.BeginInvoke(key, value, null, null);
}
void EndPut(IAsyncResult asyncResult)
{
var put = (Action<string, object>)((AsyncResult)asyncResult).AsyncDelegate;
put.EndInvoke(asyncResult);
}
這很好,因爲它知道委託類型是什麼,所以可以投射。然而,當你有兩個Put
方法時,它開始變得混亂,因爲儘管該方法返回void,但你似乎必須將其強制轉換爲強類型委託以結束調用,例如,
IAsyncResult BeginPut(string key, object value)
{
Action<string, object> put = this.cache.Put;
return put.BeginInvoke(key, value, null, null);
}
IAsyncResult BeginPut(string region, string key, object value)
{
Action<string, string, object> put = this.cache.Put;
return put.BeginInvoke(region, key, value, null, null);
}
void EndPut(IAsyncResult asyncResult)
{
var put = ((AsyncResult)asyncResult).AsyncDelegate;
var put1 = put as Action<string, object>;
if (put1 != null)
{
put1.EndInvoke(asyncResult);
return;
}
var put2 = put as Action<string, string, object>;
if (put2 != null)
{
put2.EndInvoke(asyncResult);
return;
}
throw new ArgumentException("Invalid async result", "asyncResult");
}
我希望有做這樣一個乾淨的方式,因爲我在乎委託的唯一事情就是返回類型(在這種情況下無效),而不是那個被提供給它的參數。但是我絞盡腦汁問辦公室裏的其他人,沒有人能想到答案。
我知道有一個解決方法是編寫自定義IAsyncResult
,但是這與周圍的事物,如WaitHandle
的延遲實例,我寧願有這種略帶哈克看代碼的潛在的線程問題,這樣一個艱鉅的任務,不是走這條路線。
有關如何結束調用而沒有層疊集is
檢查的任何想法?
不幸的是,認沽(字符串,對象)方法不通過認沽(字符串,字符串,對象)方法在內部,並且它是非法的傳遞null作爲第一個參數後者[這似乎因爲儘管名稱相似,它們有些不同的語義]。 – 2008-10-09 21:29:31