Q:

Modifying class variable from TPL foreach loop

I have the following console app that will delete blobs from a storage account container that are older than 7 days.
I am trying to create a feedback loop on the console screen by calling WriteNumberFilesProcessed() which increments the member variable _counter once a blob is deleted and then writes to the console.
The problem is when the last task is completing in the TPL foreach loop rather than the _counter member variable going from 29999 to 30000, it will be something further out i.e 29995.
I'm not sure what I need to do to make sure that the TPL foreach loop is getting an up-to-date member varaible?
class Program
{
    static int _counter = 0;
    static int _numBlobsToDelete = 30000;
    static int _blobCount = 0;

    static void Main(string[] args)
    {
        GetOldBlobs();

        Console.ReadLine();
    }

    static async void GetOldBlobs()
    {
        try
        {
            Stopwatch stopWatch = new Stopwatch();

            CloudStorageAccount acc = CloudStorageAccount.Parse("");
            var client = acc.CreateCloudBlobClient();
            var container = client.GetContainerReference("");
            var rollingTotal = 0;

            while (true)
            {
                stopWatch.Restart();
                Console.WriteLine($"{DateTime.Now}:\tGetting blobs older than a week in a batch of {_numBlobsToDelete}...");

                var blobs = container.ListBlobs("", true).OfType<CloudBlockBlob>().Where(b => (DateTime.UtcNow.AddDays(-7) > b.Properties.LastModified.Value.DateTime)).Take(_numBlobsToDelete).ToList();
                _blobCount = blobs.Count();
                _counter = 0;

                Console.WriteLine($"{DateTime.Now}:\tTime taken to get {_numBlobsToDelete} blobs - {stopWatch.Elapsed}");
                Console.WriteLine($"{DateTime.Now}:\tDeleting {_blobCount} blobs...");

                try
                {
                    Parallel.ForEach(blobs, blob => DeleteBlob(blob));
                }
                catch (Exception ex)
                {
                    Console.WriteLine($"{DateTime.Now}:\t{ex.Message}");
                }

                rollingTotal += _blobCount;

                Console.WriteLine($"\n{DateTime.Now}:\tTime taken to delete blobs - {stopWatch.Elapsed}");
                Console.WriteLine($"{DateTime.Now}:\t{rollingTotal} blobs deleted since startup");
                Console.WriteLine($"{DateTime.Now}:\tSleeping for 5 seconds...\n");
                await Task.Delay(5000);
            }
        }
        catch (Exception ex)
        {
            Console.WriteLine($"{DateTime.Now}:\t{ex.Message}");
        }
    }

    public static void DeleteBlob(CloudBlockBlob blob)
    {
        try
        {
            blob.Delete();
            WriteNumberFilesProcessed();
        }
        catch (Exception ex)
        {
            Console.WriteLine($"{DateTime.Now}:\t{ex.Message}\n");
        }
    }

    public static void WriteNumberFilesProcessed()
    {
        _counter++;
        Console.Write($"\r{_counter} of {_blobCount}");
    }
}

A:

Your problem is that multiple threads are calling _counter++ at once. This leads to a race condition.
To fix it, the easiest way is to use one of the Interlocked methods like so:
Interlocked.Increment(ref _counter);

Without using locking, what can happen is (given thread A and thread B):
Assume _counter has value 1:
Thread A: reads value of _counter -> 1
Thread B: reads value of _counter -> 1
Thread A: adds 1 to the value it read -> 2
Thread B: adds 1 to the value it read -> 2
Thread A: writes value back to _counter -> 2
Thread B: writes value back to _counter -> 2

And now _counter has the value 2 instead of the value it should have, 3.

