title: CastException attempting to call Action<KeyValuePair<>> delegate asynchronously
body: <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>