Real world async/await defects

Today I’m once again asking for your help.

The headliner feature for C# 5 was of course the await operator for asynchronous methods. The intention of the feature was to make it easier to write asynchronous programs where the program text is not a mass of inside-out code that emphasizes the mechanisms of asynchrony, but rather straightforward, easy-to-read code; the compiler can deal with the mess of turning the code into a form of continuation passing style.

However, asynchrony is still hard to understand, and making methods that allow other code to run before their postconditions are met makes for all manner of interesting possible bugs. There are a lot of great articles out there giving good advice on how to avoid some of the pitfalls, such as:

These are all great advice, but it is not always clear which of these potential defects are merely theoretical, and which you have seen and fixed in actual production code. That’s what I am very interested to learn from you all: what mistakes were made by real people, how were they discovered, and what was the fix?

Here’s an example of what I mean. This defect was found in real-world code; obviously the extraneous details have been removed:

Frob GetFrob()
{
  Frob result = null;
  var networkDevice = new NetworkDevice();
  networkDevice.OnDownload += 
    async (state) => { result = await Frob.DeserializeStateAsync(state); };
  networkDevice.GetSerializedState(); // Synchronous
  return result; 
}

The network device synchronously downloads the serialized state of a Frob. When it is done, the delegate stored in OnDownload runs synchronously, and is passed the state that was just downloaded. But since it is itself asynchronous, the event handler starts deserializing the state asynchronously, and returns immediately. We now have a race between GetFrob returning null, and the mutation of closed-over local result, a race almost certainly won by returning null.

If you’d rather not leave comments here — and frankly, the comment system isn’t much good for code snippets anyways — feel free to email me at eric@lippert.com. If I get some good examples I’ll follow up with a post describing the defects.

London and Budapest

I recently spent a week visiting customers and giving talks in Europe and holy goodness, never have I been in so many countries in so little time. I flew from Seattle to London, changed planes, flew to Amsterdam, visited customers in the Netherlands and Belgium, then took the Eurostar from Lille back to London, and that was just the first two days! Continue reading

ATBG: Why do enumerators avoid a bounds check?

I am back from a week in which I visited England, Holland, Belgium, France and Hungary; this is by far the most countries I’ve been to in so little time. It was great to meet so many customers; more on bicycling around Budapest in a future episode. For today though, I’ve posted on the Coverity Development Testing Blog’s continuing series Ask The Bug Guys a follow up to the previous episode. I’ll discuss why the struct-based list enumerator does not do bounds checking in its implementation of the Current property. Check it out! Thanks to reader Xi Chen for the question. Continue reading

Funniest Hungarian joke ever

No computer stuff today; since I am actually in Hungary today on business and it is the the anniversary of the happy event mentioned below, today’s FAIC is a rerun. Enjoy!


I’m back from my fabulous adventures in Austria, Romania and Canada and I had a fabulous time, as you might imagine. We were in Romania for a wedding of some close personal friends who live here in Seattle; much of the groom’s family escaped from Romania during the Communist period and settled in Austria, so we spent some time in Vienna and then headed to Bucharest, and then crossed the Carpathian mountains by bus into Transylvania for the wedding. Some of the highlights included:

Continue reading

What are the fundamental rules of pointers?

A lot of questions I see in the C tag on StackOverflow are from beginners who have never been taught the fundamental rules of pointers. (I note that these rules apply to C# as well, though it is rare to use raw pointers in C#.) A lot of introductions to pointers get caught up on the implementation details of what pointers are for a particular compiler targeting a particular architecture, so I want to be a bit more abstract than that. So, without further ado, here are the fundamentals: Continue reading

ATBG: Why does my code not crash?

For a change of page, today on the Coverity Development Testing Blog’s continuing series Ask The Bug Guys I’ll talk about mostly C and C++, with a little Java and C# thrown in at the end. I’ll discuss a very common question I see on StackOverflow in the “C” and “C++” tags: “here’s a clearly buggy program that I wrote; why does it not AV / segfault / crash when I run it?” Check it out! Continue reading

Lowering in language design, part two

Last time on FAIC I described how language designers and compiler writers use “lowering” to transform a high-level program written in a particular language into a lower-level program written using simpler features of the same language. Did you notice what this technique presupposes? To illustrate, let’s take a look at a line of the C# specification:

the operation e as T produces the same result as e is T ? (T)(e) : (T)null except that e is only evaluated once.

This seems bizarre; why does the specification say that a higher-level operation is exactly the same as a lower-level operation, except that it isn’t? Because there is no way to express the exact semantics of as in legal C# in any lowered form! The feature “evaluate a subexpression to produce its side effects and value once and then use that value several times throughout its containing expression” does not exist in C#, so the specification is forced to describe the lowering in this imprecise and roundabout way.

A nice principle of programming language design that C# does not adhere to is that all the higher-level features of the program can be expressed as lower-level features. Why is this nice to have? Well, not only is it a big convenience for writers of the specification, it also is a big convenience for writers of language analyzers. If you can programmatically transform a high-level language into an exactly equivalent program in a language with far fewer complicated concepts then your analyzer gets simpler. Continue reading

Moving this blog

Hey all, quick metablogging note.

Thanks to everyone who pointed out to me that the blog was down for the last 36+ hours. This blog was previously hosted by web.com; I chose web.com because of their alleged high uptime, alleged competence, and alleged fast customer service. As a result of my experience over the last 36 hours I’ll be moving the blog over to a different hosting service which I hope to be both more reliable and responsive. Apologies for the inconvenience.

If you’re seeing this, you’re looking at the new site; yay, it works!  Expect things to be a bit wonky for a while as not all of the formatting and whatnot transferred over.

While I was at it, I moved the content from my blog about building a backyard aluminum foundry to https://ericlippert.com/category/foundry/. I haven’t done much casting over the last year or so but hope to get back into it this summer.

In related news, as a consequence of changing hosting services: the purple is back, infinite scrolling is on, social media buttons are enabled, AdWords have been replaced with WordAds (!), footnotes are broken, comments are too narrow. I’ll take the good with the bad.