Re: ConcurrentQueue и синхронизация
От: RushDevion Россия  
Дата: 18.02.20 10:13
Оценка: 3 (1) +1
Описано, конечно сумбурно.
Но похоже на классический producer/consumer.
Это проще на BlockingCollection сделать.
Типа такого:
class Processor<T>    
{    
    private BlockingCollection<Job> jobs = new BlockingCollection<Job>
    
    private class Job {
        public readonly T Data; 
        public readonly Action Callback;
        public Job(T data, Action callback = null) { ... }
    }
        
    public void AddJob(T data) {
        jobs.Add(new Job(data));
    }

    public void AddJob(T data, Action onCompleted) {
        jobs.Add(new Job(data, onCompleted));
    }

    public void Start(CancellationToken ct = default) {
        foreach(var job in jobs.GetConsumingEnumerable(ct)) {
            SaveToDb(item.Data);
            if (item.Callback !== null) {
                Task.Run(() => item.Callback());
            }
        }
    }
    
    public void Stop() {
        jobs.CompleteAdding();
    }
    
    private void SaveToDb() { ... }
}


// Обычный добавлятель
processor.AddJob(new Data());

// Добавлятель, которому надо подождать
var data = new Data(); 
processor.AddJob(data, () => {
    // Data saved, keep processing
});


Или можно на TaskCompletionSource переписать, т.е. будет что-то типа Task AddJobAndWait(T data),
под которым лежит TaskCompletionSource и processor после сохранения будет делать tcs.SetResult(true).
Тогда добавлятель сможет ждать или await'ить на таске.
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.