Czy istnieje szansa że się zrobi nie po kolei?

0

Hej, mam taki koncept:

public class Queue
    {
        public Queue()
        {
            locker = new object();
            queue = new Dictionary<int, object>();
        }

        public async Task<int> AddToQueueAsync(object item)
        {
            return await Task.Run(() =>
            {
                var randomID = 1234234;

                lock (locker) queue.Add(randomID, item);

                return randomID;
            });
        }
        public async Task ReleaseQueueAsync()
        {
            await Task.Run(() =>
            {
                Dictionary<int, object> copy;
                lock (locker)
                {
                    copy = new Dictionary<int, object>(queue);
                    queue.Clear();
                }

                foreach (var item in copy) { } // ...
            });
        }

        private readonly object locker;
        private readonly Dictionary<int, object> queue;
    }

i się zastanawiam czy jak wywołam tak na luźno:

AddToQueueAsync(null);
ReleaseQueueAsync();

to może się zdarzyć tak że nie zdąży się dodać do kolejki przed jej zwolnieniem? Że jakimś cudem lock w metodzie ReleaseQueueAsync wejdzie jako pierwszy?

3

Task.Run() nie daje żadnych gwarancji odnośnie czasu oraz kolejności wykonywania zadań (mogą np. wykonywać się obydwa w tym samym czasie na dwóch różnych rdzeniach[1]) - aby mieć pewność, że wszystko zostaje wykonane w odpowiedniej kolejności, musisz dorzucić await:

await AddToQueueAsync(null);
await ReleaseQueueAsync();

[1] https://docs.microsoft.com/en-us/dotnet/standard/threading/the-managed-thread-pool

1

Imo jest taka szansa.
Ale po co takie kombinacje skoro masz klasę ConcurentDictionary?
Do synchronizacji między wątkami możesz użyć m.in ManualResetEvent

1 użytkowników online, w tym zalogowanych: 0, gości: 1