我似乎無法找出爲什麼我收到一個InvalidCastException運行下面的代碼:CastException試圖調用操作<KeyValuePair <>>委託異步
var item = new KeyValuePair<string, string>("key", "value");
Action<KeyValuePair<string, string>> kvrAction =
kvr =>Console.WriteLine(kvr.Value);
var result = kvrAction.BeginInvoke(item, null, null);
kvrAction.EndInvoke(result);
異常信息:
Test method Utilities.Tests.IEnumerableExtensionTests.ProveDelegateAsyncInvokeFailsForKeyValuePair threw exception: System.Runtime.Remoting.RemotingException: The argument type '[key, value]' cannot be converted into parameter type 'System.Collections.Generic.KeyValuePair`2[System.String,System.String]'.
---> System.InvalidCastException: Object must implement IConvertible..
任何援助將不勝感激=)此代碼似乎與我拋出的任何東西,除了一個KeyValuePair <>。
更新:看起來這種情況存在於任何結構中。我沒有注意到KeyValuePair <>是一個結構,所以只能用類進行測試。我仍然不明白爲什麼會出現這種情況。
更新2:Simon的答案有助於確認此行爲是意外的,但是實施自定義類型對於我正在嘗試執行的操作無效。我試圖在IEnumerable <>上爲每個項目異步執行一個委託來實現一個擴展方法。我注意到運行測試針對通用Dictionary對象的錯誤。
public static IEnumerable<T> ForEachAsync<T>(this IEnumerable<T> input, Action<T> act)
{
foreach (var item in input)
{
act.BeginInvoke(item, new AsyncCallback(EndAsyncCall<T>), null);
}
return input;
}
private static void EndAsyncCall<T>(IAsyncResult result)
{
AsyncResult r = (AsyncResult)result;
if (!r.EndInvokeCalled)
{
var d = (Action<T>)((r).AsyncDelegate);
d.EndInvoke(result);
}
}
我寧願不限制與T約束的方法,以確保只有類用於所以我重構方法如下繞過與BeginInvoke的問題,但我還沒有與TreadPool直接工作過並希望確保我不會錯過任何重要的事情。
public static IEnumerable<T> ForEachAsync<T>(this IEnumerable<T> input, Action<T> act)
{
foreach (var item in input)
ThreadPool.QueueUserWorkItem(obj => act((T)obj), item);
return input;
}
感謝西蒙,我很高興我不只是忽視的東西傻了。我認爲它在框架中導致類型檢查失敗導致檢查IConvertable接口的錯誤。不幸的是,實現一個自定義類型不是我想要做的選項。我更詳細的來。 – Venr 2009-02-27 16:48:34