Информация об изменениях

Сообщение Re: .net core и async lock от 06.04.2021 13:58

Изменено 07.04.2021 7:10 Serginio1

Re: .net core и async lock
Здравствуйте, Sharov, Вы писали:

Можно пришпандорить аналог асихронной очереди

https://docs.microsoft.com/ru-ru/dotnet/standard/asynchronous-programming-patterns/consuming-the-task-based-asynchronous-pattern#asyncproducerconsumercollection
public class AsyncProducerConsumerCollection<T>
{
    private readonly Queue<T> m_collection = new Queue<T>();
    private readonly Queue<TaskCompletionSource<T>> m_waiting =
        new Queue<TaskCompletionSource<T>>();

    public void Add(T item)
    {
        TaskCompletionSource<T> tcs = null;
        lock (m_collection)
        {
            if (m_waiting.Count > 0) tcs = m_waiting.Dequeue();
            else m_collection.Enqueue(item);
        }
        if (tcs != null) tcs.TrySetResult(item);
    }

    public Task<T> Take()
    {
        lock (m_collection)
        {
            if (m_collection.Count > 0)
            {
                return Task.FromResult(m_collection.Dequeue());
            }
            else
            {
                var tcs = new TaskCompletionSource<T>();
                m_waiting.Enqueue(tcs);
                return tcs.Task;
            }
        }
    }
}


С этой структурой данных на месте можно написать следующий код.
C#

Копировать
private static AsyncProducerConsumerCollection<int> m_data = …;

Сделаем сигнальным
m_data.Add(1);



await m_data.Take();//Типа Monitor.Enter
......

m_data.Add(1);// Monitor.Exit()
Re: .net core и async lock
Здравствуйте, Sharov, Вы писали:

Можно пришпандорить аналог асихронной очереди

https://docs.microsoft.com/ru-ru/dotnet/standard/asynchronous-programming-patterns/consuming-the-task-based-asynchronous-pattern#asyncproducerconsumercollection
public class AsyncProducerConsumerCollection<T>
{
    private readonly Queue<T> m_collection = new Queue<T>();
    private readonly Queue<TaskCompletionSource<T>> m_waiting =
        new Queue<TaskCompletionSource<T>>();

    public void Add(T item)
    {
        TaskCompletionSource<T> tcs = null;
        lock (m_collection)
        {
            if (m_waiting.Count > 0) tcs = m_waiting.Dequeue();
            else m_collection.Enqueue(item);
        }
        if (tcs != null) tcs.TrySetResult(item);
    }

    public Task<T> Take()
    {
        lock (m_collection)
        {
            if (m_collection.Count > 0)
            {
                return Task.FromResult(m_collection.Dequeue());
            }
            else
            {
                var tcs = new TaskCompletionSource<T>();
                m_waiting.Enqueue(tcs);
                return tcs.Task;
            }
        }
    }
}


С этой структурой данных на месте можно написать следующий код.
C#

Копировать
private static AsyncProducerConsumerCollection<int> m_data = …;

Сделаем сигнальным
m_data.Add(1);


…
await m_data.Take();//Типа Monitor.Enter
......

m_data.Add(1);// Monitor.Exit()