Facilitating the Spread of Knowledge and Innovation in Professional Software Development

Write for InfoQ


Choose your language

InfoQ Homepage News Asynchronous Gotchas in C#

Asynchronous Gotchas in C#

This item in japanese

Sometimes the best way to understand pitfalls in one language is to see how another language prevents them. Tomas Petricek, author of Real-World Functional Programming, discusses six common mistakes found in asynchronous C# code and demonstrates how F# makes them less likely to occur.

While we encourage you read his entire article, titled Async in C# and F#: Asynchronous gotchas in C#, here is a brief synopsis of Tomas covers.

Async does not run asynchronously: Only code that appears after the first await statement is run asynchronously.

Ignoring results: Forgetting to await on the task returned by a function can result in out-of-order execution.

Async void methods: Asynchronous functions that return “async void” instead of “async Task” cannot be awaited, effectively causing the same problem as ignoring results.

Async void lambda functions: This occurs when a function accepts an Action delegate but not a Func<…, Task> delegate. Again, the async function is not going to be awaited on.

Nesting of tasks: In the statement “await Task.Factory.StartNew(async () => { await Task.Delay(1000); });” the first and second await statements are completely unrelated. This means the first await will complete before second await, and the associated 1000 ms delay, are honored.

Not running asynchronously: By using Task.Wait(), the entire call stack can be forced into a synchronous mode.

For those of you unfamiliar with F#, you may be surprised to learn that async workflows in F# are not based on the Task and Task<T> types. Instead, F# uses its own type known as Async<T>.

Rate this Article