Лучший способ справиться со сном в обработчиках событий в однопоточном API?

Я использую API событий, не требующий обеспечения безопасности потоков. wait(), и из этого вызова отправляются обработчики событий. Я хочу иметь возможность в обработчике событий какое-то время «спать». В настоящее время у меня есть планировщик, который планирует функции, которые должны быть вызваны позже, и есть небольшой прием, который позволяет мне использовать Scheduler.Sleeper (some_ienumerator) в качестве обработчика событий, поэтому я могу использовать временные интервалы как своего рода сон. Есть ли лучшее решение? Если бы в C # были Fibers в стиле Ruby, я мог бы сделать так, чтобы в планировщике была функция Sleep (), которую я мог бы вызывать, и материал сна мог бы находиться в функции, вызываемой обработчиком событий, а не непосредственно обработчиком. Что еще я могу сделать, учитывая отсутствие удобных в использовании волокон?

ИЗМЕНИТЬ ДЛЯ УТОЧНЕНИЯ: Я вызываю wait(n), где n - количество времени, и во время этого вызова ожидания API вызывает обработчики событий. Причина, по которой я хочу «спать» в некоторых из этих обработчиков, заключается в том, что это для игры, где после нажатия на что-либо объект может, например, на секунду светиться.


person Sgeo    schedule 10.03.2010    source источник
comment
Может быть, это только я, но мне сложно определить, что вы хотите делать. Я изо всех сил стараюсь никогда не уснуть в любом написанном мной коде. Я уверен, что для них есть время и место, но они слишком много раз кусали меня, и обычно их ставили из-за каких-то временных проблем. Они оказываются скорее пластырем, чем решением. Сказав это, я все еще не понимаю вашего намерения на основе вашего описания, поэтому я могу упустить цель вопроса   -  person Rob Goodwin    schedule 10.03.2010


Ответы (1)


Ваш вопрос не очень ясен. Вопрос в том, чем вы хотите заниматься в «ожидании»? Если вы говорили, например, о приложениях WinForms с графическим интерфейсом пользователя, тогда вы хотели бы обрабатывать другие события во время ожидания (что можно сделать с помощью метода Application.DoEvents), поэтому, может быть, вы могли бы использовать аналогичное решение?

Облегченная кооперативная многопоточность (вероятно, похожая на волокна Ruby) может быть смоделирована на C # с помощью итераторов (ключевое слово yield return). Намного лучший способ сделать что-то подобное в .NET - использовать F #, где вы можете делать такие вещи более элегантно, используя асинхронные рабочие процессы. Вот статья, демонстрирующая написание однопоточного графического интерфейса пользователя, в котором вы можете «ждать» возникновения события без блокировки:

Как я уже сказал, вы можете смоделировать это на C #, используя yield return. Вот моя попытка:

Другой подход, основанный на yield return, - это среда выполнения параллелизма и координации, которая немного сложнее, но был разработан в первую очередь для C #.

person Tomas Petricek    schedule 10.03.2010
comment
Проблема с yield return (по крайней мере, так, как я его использую, и мое понимание второй ссылки [первая упоминает C #]) заключается в том, что функция [A] не может просто вызвать другую функцию [B], которая происходит использовать yield return и сам быть остановленным, ожидая, пока асинхронная функция выполнит обратный вызов B и оттуда будет возобновлена ​​A. - person Sgeo; 10.03.2010
comment
Если я вас правильно понял, это именно то, что делает последний пример кода в статье. Метод ReadToEndAsync возвращает IEnumerable<IAsync> (и содержит yield return). В статье мы можем использовать ExecuteAsync<string>(), чтобы превратить его в значение, представляющее асинхронное вычисление (типа Async<string>), а затем вы можете вызвать это вычисление из внешнего метода (используя yield return). Я думаю, в общем, вам нужно использовать какой-то промежуточный тип для представления вычислений. - person Tomas Petricek; 10.03.2010
comment
Я не совсем прочитал всю статью, прежде чем комментировать ›.›. Спасибо, эта ссылка (Асинхронное программирование на C # с использованием итераторов) кажется идеальной! [Тем не менее, мне все еще нужно попробовать]. - person Sgeo; 10.03.2010