Страницы

Поиск по вопросам

вторник, 10 декабря 2019 г.

Как на C# выполнить метод в “очереди” раз в секунду, а не чаще?

#c_sharp #очередь


Мне нужно, как только происходит определённое событие "Данные обновились"- запускать
метод X -"Разослать обновлённые данные клиентам".
Но если событие вызывается, скажем 50 раз в секунду- нет необходимости столько же
раз сразу же запускать метод X, создавая нагрузку.
Можно ли как-то поставить событие в очередь, и если очередь есть, запустить метод
X- то выполнить только самое последнее событие? 



Вариант 1: Есть 50 клиентов онлайн. Подключается 51-й. Я рассылаю 50+1 клиенту список
клиентов онлайн. Подкл 52-й - делаем то же самое.
Вариант 2: Есть 50 клиентов онлайн. Подключается 51-й. Отсылаю так-же всё. Но тут
подключается пара десятков человек и я должен так же всё рассылать.

Я хочу, если только что была рассылка- не отправлять сразу, а ждать, скажем, секунду
и потом, если был запрос разослать данные- то сделать рассылку таблицы на текущий момент
времени. Таким образом все клиенты получили данные- пусть не моментально, а на секунду
позже, зато я не слал очень много раз.
Ну как-то так.
Как такое реализовать?
    


Ответы

Ответ 1



Ну, вы можете завести таймер и добавить в него немного логики. Вот пример: class Program { public static event EventHandler NewClientArrived; static void X() => Console.WriteLine("\n\tSending notifications"); static void Main(string[] args) { var timer = new System.Timers.Timer(3000) { AutoReset = false }; timer.Elapsed += (sender, timerargs) => X(); NewClientArrived += (sender, eventargs) => { if (!timer.Enabled) timer.Start(); }; // запускаем симуляцию прихода клиентов while (Console.ReadKey().Key != ConsoleKey.Escape) NewClientArrived(null, EventArgs.Empty); } } Если вы используете RX Extensions, можно попробовать так: static void Main(string[] args) { using (Observable.FromEventPattern(typeof(Program), nameof(NewClientArrived)) .Sample(TimeSpan.FromSeconds(1)) .Subscribe(_ => X())) { // запускаем симуляцию прихода клиентов while (Console.ReadKey().Key != ConsoleKey.Escape) NewClientArrived(null, EventArgs.Empty); } }

Ответ 2



Как вариант, можно хранить дату последнего срабатывания события. Когда возбуждается событие, проверяй последний дату выполнения. Если ты видишь, что с момента последнего срабатывания события не прошло и секунды, делай return.

Комментариев нет:

Отправить комментарий