title: Unexpected behavior when passing async Actions around
body: <p>I'm pretty familiar with the async/await pattern, but I'm bumping into some behavior that strikes me as odd. I'm sure there's a perfectly valid reason why it's happening, and I'd love to understand the behavior.</p>
  
  <p>The background here is that I'm developing a Windows Store app, and since I'm a cautious, conscientious developer, I'm unit testing everything. I discovered pretty quickly that the <code>ExpectedExceptionAttribute</code> doesn't exist for WSAs. Weird, right? Well, no problem! I can more-or-less replicate the behavior with an extension method! So I wrote this:</p>
  
  <pre><code>public static class TestHelpers
  {
      // There's no ExpectedExceptionAttribute for Windows Store apps! Why must Microsoft make my life so hard?!
      public static void AssertThrowsExpectedException&lt;T&gt;(this Action a) where T : Exception
      {
          try
          {
              a();
          }
          catch (T)
          {
              return;
          }
  
          Assert.Fail("The expected exception was not thrown");
      }
  }
  </code></pre>
  
  <p>And lo, it works beautifully.</p>
  
  <p>So I continued happily writing my unit tests, until I hit an async method that I wanted to confirm throws an exception under certain circumstances. "No problem," I thought to myself, "I can just pass in an async lambda!"</p>
  
  <p>So I wrote this test method:</p>
  
  <pre><code>[TestMethod]
  public async Task Network_Interface_Being_Unavailable_Throws_Exception()
  {
      var webManager = new FakeWebManager
      {
          IsNetworkAvailable = false
      };
  
      var am = new AuthenticationManager(webManager);
      Action authenticate = async () =&gt; await am.Authenticate("foo", "bar");
      authenticate.AssertThrowsExpectedException&lt;LoginFailedException&gt;();
  }
  </code></pre>
  
  <p>This, surprisingly, throws a runtime error. It actually <em>crashes</em> the test-runner!</p>
  
  <p>I made an overload of my <code>AssertThrowsExpectedException</code> method:</p>
  
  <pre><code>public static async Task AssertThrowsExpectedException&lt;TException&gt;(this Func&lt;Task&gt; a) where TException : Exception
  {
      try
      {
          await a();
      }
      catch (TException)
      {
          return;
      }
  
      Assert.Fail("The expected exception was not thrown");
  }
  </code></pre>
  
  <p>and I tweaked my test:</p>
  
  <pre><code>[TestMethod]
  public async Task Network_Interface_Being_Unavailable_Throws_Exception()
  {
      var webManager = new FakeWebManager
      {
          IsNetworkAvailable = false
      };
  
      var am = new AuthenticationManager(webManager);
      Func&lt;Task&gt; authenticate = async () =&gt; await am.Authenticate("foo", "bar");
      await authenticate.AssertThrowsExpectedException&lt;LoginFailedException&gt;();
  }
  </code></pre>
  
  <p>I'm fine with my solution, I'm just wondering exactly why everything goes pear-shaped when I try to invoke the async <code>Action</code>. I'm guessing because, as far as the runtime is concerned, it's <em>not</em> an <code>Action</code>, I'm just cramming the lambda into it. I know the lambda will happily be assigned to either <code>Action</code> or <code>Func&lt;Task&gt;</code>. </p>