You can still use InterLocked , but then you need to convert the decimal mark to Int64 . When converting, you need to decide how many decimal places you want to keep for accuracy. So, for example, you want to save 4 decimal places, you can 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;
Remember that you will lose accuracy, depending on how many decimal places you would like to keep. And Decimal.MaxValue is 79,228,162,514,264,337,593,543,950,335 , while Int64.MaxValue is 9,223,372,036,854,775,807 . So very large numbers do not fit. Keeping 4 decimal places, the largest number before the Int64 overflow will be 9,223,372,036,854,775,807 / 10000 = 922,337,203,685,477
I use it this way since the numbers here will never exceed 1,000,000,000, and I am sure that using InterLocked this way is faster in the Parallel.For loop, using lock or mutex.