Note that there are some explanatory texts on larger screens.

plurals
  1. POCastException attempting to call Action<KeyValuePair<>> delegate asynchronously
    primarykey
    data
    text
    <p>I can't seem to figure out why I am getting an InvalidCastException running the following code:</p> <pre><code>var item = new KeyValuePair&lt;string, string&gt;("key", "value"); Action&lt;KeyValuePair&lt;string, string&gt;&gt; kvrAction = kvr =&gt;Console.WriteLine(kvr.Value); var result = kvrAction.BeginInvoke(item, null, null); kvrAction.EndInvoke(result); </code></pre> <p>Exception Info:</p> <pre><code>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]'. ---&gt; System.InvalidCastException: Object must implement IConvertible.. </code></pre> <p>Any assistance would be appreciated =) This code seems to work with anything I throw at it except a KeyValuePair&lt;>.</p> <p>Update: It appears this condition exists for any struct. I hadn't noticed KeyValuePair&lt;> was a struct and so was only testing with classes. I still don't understand why this is the case though. </p> <p>Update 2: Simon's answer helped confirm this behavior is unexpected, however implementing a custom type won't work for what I'm trying to do. I am trying to implement an extension method on IEnumerable&lt;> to execute a delegate Asynchronously for each item. I noticed the error running tests against a generic Dictionary object.</p> <pre><code> public static IEnumerable&lt;T&gt; ForEachAsync&lt;T&gt;(this IEnumerable&lt;T&gt; input, Action&lt;T&gt; act) { foreach (var item in input) { act.BeginInvoke(item, new AsyncCallback(EndAsyncCall&lt;T&gt;), null); } return input; } private static void EndAsyncCall&lt;T&gt;(IAsyncResult result) { AsyncResult r = (AsyncResult)result; if (!r.EndInvokeCalled) { var d = (Action&lt;T&gt;)((r).AsyncDelegate); d.EndInvoke(result); } } </code></pre> <p>I would rather not limit the method with a constraint on T to ensure only classes are used so I have refactored the method as follows to get around the problem with BeginInvoke but I have not worked with the TreadPool directly before and would like to make sure I am not missing anything important.</p> <pre><code> public static IEnumerable&lt;T&gt; ForEachAsync&lt;T&gt;(this IEnumerable&lt;T&gt; input, Action&lt;T&gt; act) { foreach (var item in input) ThreadPool.QueueUserWorkItem(obj =&gt; act((T)obj), item); return input; } </code></pre>
    singulars
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload