Doing this is OK:
Thread A:
var incremented_counter = Interlocked.Increment(ref counter);
Console.WriteLine(incremented_counter);
Thread B:
Interlocked.Increment(ref counter);
And doing this is OK:
Thread A:
lock (the_lock) {
   ++counter;
   Console.WriteLine(counter); 
}
Thread B:
lock (the_lock) {
   ++counter;
}
Doing this is OK but redundant:
Thread A:
lock (the_lock) {
    var incremented_counter = Interlocked.Increment(ref counter);
    Console.WriteLine(incremented_counter);
}
Thread B:
lock (the_lock) {
    Interlocked.Increment(ref counter);
}
But doing this is not OK:
Thread A:
Interlocked.Increment(ref counter);
Console.WriteLine(counter);
Thread B:
Interlocked.Increment(ref counter);
Nor is it doing this:
Thread A:
lock (the_lock) {
   ++counter;
   Console.WriteLine(counter); 
}
Thread B:
Interlocked.Increment(ref counter);
Nor is it doing this:
Thread A:
var incremented_counter = Interlocked.Increment(ref counter);
Console.WriteLine(incremented_counter);
Thread B:
lock (the_lock) {
   ++counter;
}
(BTW, don't use lock on this.)