C# Interlocked Exchange

Martin picture Martin · Jul 12, 2009 · Viewed 9.8k times · Source

I have a bit of my game which looks like this:

public static float Time;

float someValue = 123;
Interlocked.Exchange(ref Time, someValue);

I want to change Time to be a Uint32; however, when I try to use UInt32 instead of float for the values, it protests that the type must be a reference type. Float is not a reference type, so I know it's technically possible to do this with non-reference types. Is there any practical way to make this work with UInt32?

Answer

Jon Skeet picture Jon Skeet · Jul 12, 2009

There's an overload for Interlocked.Exchange specifically for float (and others for double, int, long, IntPtr and object). There isn't one for uint, so the compiler reckons the closest match is the generic Interlocked.Exchange<T> - but in that case T has to be a reference type. uint isn't a reference type, so that doesn't work either - hence the error message.

In other words:

As for what to do, the options are any of:

  • Potentially use int instead, as Marc suggests.
  • If you need the extra range, think about using long.
  • Use uint but don't try to write lock-free code

Although obviously Exchange works fine with some specific value types, Microsoft hasn't implemented it for all the primitive types. I can't imagine it would have been hard to do so (they're just bits, after all) but presumably they wanted to keep the overload count down.