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

Сообщение Re: SynchronizationContext a-la node.js от 30.09.2016 9:10

Изменено 30.09.2016 9:13 Serginio1

Здравствуйте, SuhanovSergey, Вы писали:

SS>Хочется иметь SynchronizationContext

SS>- который бы сериализовал колбэки, так что только один колбэк испольняется в момент времени
SS>- не являлся бю UI-ным SynchronizationContext-ом, а испльзовал бы тред пул. Никакой тред не должен спать, ожидая колбэков.

SS>Нужно для IO-bound фоновый задачи, которая запускает параллельные составные IO таски и не хочет синзронизировать доступ к общим переменным между await-ами.


Может я не понял вопроса, но вот здесь Consuming the Task-based Asynchronous Pattern

Есть пример асинхронной очереди


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;
            }
        }
    }
}

Используя эту структуру данных, можно написать следующий код:

private static AsyncProducerConsumerCollection<int> m_data = …;
…
private static async  Task ConsumerAsync()
{
    while(true)
    {
        int nextItem = await m_data.Take();
        ProcessNextItem(nextItem);
    }
}
…
private static void Produce(int data)
{
    m_data.Add(data);
}
Re: SynchronizationContext a-la node.js
Здравствуйте, SuhanovSergey, Вы писали:

SS>Хочется иметь SynchronizationContext

SS>- который бы сериализовал колбэки, так что только один колбэк испольняется в момент времени
SS>- не являлся бю UI-ным SynchronizationContext-ом, а испльзовал бы тред пул. Никакой тред не должен спать, ожидая колбэков.

SS>Нужно для IO-bound фоновый задачи, которая запускает параллельные составные IO таски и не хочет синзронизировать доступ к общим переменным между await-ами.


Может я не понял вопроса, но вот здесь Consuming the Task-based Asynchronous Pattern

Есть пример асинхронной очереди


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;
            }
        }
    }
}

Используя эту структуру данных, можно написать следующий код:

private static AsyncProducerConsumerCollection<int> m_data = …;
…
private static async  Task ConsumerAsync()
{
    while(true)
    {
        int nextItem = await m_data.Take();
        ProcessNextItem(nextItem);
    }
}
…
private static void Produce(int data)
{
    m_data.Add(data);
}


Там же

Пространство имен System.Threading.Tasks.Dataflow включает тип BufferBlock<T>, который можно использовать таким же образом, но без построения пользовательского типа коллекции:


private static BufferBlock<int> m_data = …;
…
private static async  Task ConsumerAsync()
{
    while(true)
    {
        int nextItem = await m_data.ReceiveAsync();
        ProcessNextItem(nextItem);
    }
}
…
private static void Produce(int data)
{
    m_data.Post(data);
}