我似乎无法找出为什么我收到一个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