Today I learned something new and I love that!
I was looking at some code that looked like this:
try
{
await obj.GetSomeAsync();
Assert.True(false, "SomeException was not thrown");
}
catch (SomeException)
{
}
That’s odd. We’re using xUnit. Why not use the Assert.Throws method? So I tried with the following naïve code.
Assert.Throws<SomeException>(() => await obj.GetSomeAsync());
Well that didn’t work. I got the following helpful compiler error:
error CS4034: The 'await' operator can only be used within an async lambda expression. Consider marking this lambda expression with the 'async' modifier.
Oh, I never really thought about applying the async keyword to a lambda expression, but it makes total sense. So I tried this:
Assert.Throws<SomeException>(async () => await obj.GetSomeAsync());
Hey, that worked! I rushed off to tell the internets on Twitter.
But I made a big mistake. That only made the compiler happy. It doesn’t actually work. It turns out that Assert.Throws takes in an Action and thus that expression doesn’t return a Task to be awaited upon. Stephen Toub explains the issue in this helpful blog post, Potential pitfalls to avoid when passing around async lambdas.
Read more: haacked
QR: