Do I need to use lock when closing?

Consider this piece of code that creates a closure around counter:

uint counter = 0xFFFF;
someList.AsParallel().ForEach(a => { uint tmp = ++counter });

(Please put aside the obvious problem of using a counter in parallel foreach for a minute).

Will it tmpever be evaluated to 0x0000 or 0x1FFFF?

My reasoning: to increase counterfrom 0xFFFF to 0x10000, at least a two-byte CPU command is required, which can be interrupted by multi-threaded processing. If it is interrupted, there is a possibility that only one byte will be updated counter- it can be temporarily set to 0x00000 or 0x1FFFF.

Should I write this as:

uint counter = 0xFFFF;
someList.AsParallel().ForEach(a => { uint tmp = Interlocked.Increment(counter) });

...

And if I get rid of AsParallel, am I completely safe?

+4
2

, Interlocked.Increment, , . , , , .

:

public class C
{
    [CompilerGenerated]
    private sealed class <>c__DisplayClass0_0
    {
        public uint counter;
        internal void <M>b__0(int a)
        {
            uint num = this.counter + 1u;
            this.counter = num;
        }
    }
    public void M()
    {
        C.<>c__DisplayClass0_0 <>c__DisplayClass0_ = new C.<>c__DisplayClass0_0();
        <>c__DisplayClass0_.counter = 65535u;
        List<int> source = new List<int> {
            1,
            2,
            3
        };
        source.AsParallel<int>().ForAll(new Action<int>(<>c__DisplayClass0_.<M>b__0));
    }
}

AsParallel, ?

, . , , , , .

+2

. - . - . , , , ( ).

0

Source: https://habr.com/ru/post/1668328/


All Articles