Агрегатор событий WPF - ожидание завершения предыдущего выполнения - PullRequest
0 голосов
/ 31 марта 2020

Я работаю над приложением WPF с использованием Prism. Я использую EventAggregator для связи между моделями представления.

public class PublisherViewModel
{
   _eventAggregator.GetEvent<RefreshEvent>().Publish("STOCKS");
}
public class SubscriberViewModel
{
    public SubscriberViewModel(IEventAggregator ea)
    {
        ea.GetEvent<RefreshEvent>().Subscribe(RefreshData);
    }

    void RefreshData(string category)
    {
        Task.Run(() =>
        {
                //Long Running Operation

                Dispatcher.Invoke(() =>
                {
                     //Refresh UI
                });
        });
    }
}

PublisherViewModel может публиковать sh событие один за другим. Однако при SubscriberViewModel , поскольку у меня есть длительная Задача , и я не ожидаю (чего я не могу) второй запрос, поступающий от издателя, сразу начинает выполнение. На SubscriberViewModel Я хочу обработать все входящие запросы так, чтобы они выполнялись один за другим в порядке их поступления.

Я думаю обработать это с помощью механизма на основе очереди.

Не могли бы вы предложить мне лучшие практики для того же.

Спасибо !!

Обновление: - Я использовал следующий подход

public class BlockingQueue<T> wehre T : class
{
    private readonly BlockingCollection<JobQueueItem<T>> _jobs;
    public BlockingQueue(int upperBound)
    {
        _jobs = new BlockingCollection<JobQueueItem<T>>(upperBound);
        var thread = new Thread(new ThreadStart(OnStart));
        thread.IsBackground = true;
        thread.Start();
    }

    public void Enqueue(T parameter, Func<T, Task> action)
    {
        _jobs.Add(new JobQueueItem<T> { Parameter = parameter, JobAction = action });
    }

    private void OnStart()
    {
        foreach (var job in _jobs.GetConsumingEnumerable(CancellationToken.None))
        {
            if (job != null && job.JobAction != null)
            {
                job.Action.Invoke(job.Parameter).Wait();
            }
        }
    }

    private class JobQueueItem<T>
    {
        internal T Parameter { get; set; }
        internal Func<T, Task> JobAction { get; set; }
    }
}
public class SubscriberViewModel
{
    BlockingQueue<RefreshEventArgs> RefreshQueue = new ...;

    //inside Subscribed method
    RefreshQueue.Enqueue(args, RefreshData);
}

Пожалуйста, предложите. Спасибо!

1 Ответ

0 голосов
/ 31 марта 2020

Я думаю, чтобы справиться с этим, используя механизм на основе очередей.

Это путь к go. Настройте очередь (возможно, асинхронную очередь), извлеките события sh в подписчике и используйте их из рабочей задачи.

Поток данных TPL - это один из вариантов: создать ActionBlock<string> от обработчика и опубликуйте события в нем по мере их поступления.

...