I have a decimal
variable that is accessed from multiple threads at the same time. Interlocked
class functions do not support decimals at all, so the only approach I'm left with is using lock(){}
. It seems to be an overkill.
It there some other way to add value to decimal
variable in a thread-safe way?
These operators are not thread-safe. Imagine two threads that increment a variable. If they do the operation serially, the variable ends up correctly incremented twice.
Increments a specified variable and stores the result, as an atomic operation. Increment(Int64) Increments a specified variable and stores the result, as an atomic operation.
To initialize a decimal variable, use the suffix m or M. Like as, decimal x = 300.5m;. If the suffix m or M will not use then it is treated as double.
The methods of this class help protect against errors that can occur when the scheduler switches contexts while a thread is updating a variable that can be accessed by other threads, or when two threads are executing concurrently on separate processors.
You can still use InterLocked
, but then you have to convert the decimal to an Int64
. With the conversion you have to decide how many decimal places you want to preserve for precision. So for example, you want to preserve 4 decimal places, you could do something like this:
//Declare up front accessible from all threads
Int64 totalAmount = 0;
//Inside the thread you do this
var amount = (Int64)(decimalAmount * 10000); //10.000 is to preserve 4 decimal places
Interlocked.Add(ref totalAmount, amount);
//After all threads have finished, go back to decimal type.
var totalDecimalAmount = totalAmount / 10000;
Be aware that you will lose precision, depending on how many decimal places you would like to preserve. And Decimal.MaxValue
is 79,228,162,514,264,337,593,543,950,335
whereas Int64.MaxValue
is 9,223,372,036,854,775,807
. So very large numbers won't fit. Preserving 4 decimal places, the largest number before the Int64 would overflow is 9,223,372,036,854,775,807 / 10000 = 922,337,203,685,477
I use it this way as numbers here will never go above 1,000,000,000 and I am sure that using Interlocked
this way is faster in a Parallel.For loop then using a lock
or mutex.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With