2013-03-23 3 views
0

У меня есть обработчик событий (из таймера), который перерисовывает каждые x миллисекунд.проверка завершения метода async void

Хотя, по-видимому, не рекомендуется использовать методы async void, это, по-видимому, неверно для обработчиков событий, так как разработчик не вызывает их из других методов.

Моя проблема Я заметил, что когда процессор имеет большую рабочую нагрузку (фоновые задачи и т. Д.), Выполняются перекрывающиеся вызовы для перерисовки.

Мне удалось обойти это, установив флаг (переменная bool), чтобы указать, что чертеж завершен (и не вызывает мой метод draw, если этот флаг не является истинным), но я слышал, что приложения для хранения в Windows могут быть отклонен для опроса в асинхронной деятельности.

private void _timer_Tick(object sender, object e) 
{ 
    if (drawingFinished == true) 
    { 
     drawingFinished = false; 

     // drawingFinished set to true at the end of this method 
     DrawVideoFrame();  
    } 
} 

Кроме того, вы не можете добавлять блокировки для асинхронных методов.

Что является лучшей практикой здесь? Как мне это сделать?

+0

Это не отвечает на ваш вопрос, но вместо использования логического флага вы можете просто кэшировать задачу и проверить, завершено ли она. Что на самом деле делает DrawVideoFrame? –

+0

Интересная идея, pm_2. Я думаю, что я не смог бы получить задачу до тех пор, пока метод, возвращающий задачу, не завершится. – micahhoover

+0

Нет - вы можете просто создать задачу как переменную и использовать ее позже в потоке процесса. –

ответ

1

Мой метод выглядит, как это сейчас:

private void _timer_Tick(object sender, object e) 
{ 
    _timer.Stop(); 

    DrawVideoFrame(); // calls timer.Start() as one the last line 
} 

Я вижу, за и против, чтобы это решение:

Pros: (1) Он чувствует себя менее, как ляп (зр?). (2) У Microsoft меньше оснований отклонять мое приложение, потому что я не проверяю условие завершения. (3) Мой метод рисования определенно не прерывается сейчас. (4) Несмотря на все мои усилия, он работает по своему желанию;)

Против: Я не планирую, когда кадры будут нарисованы больше. Поэтому вместо того, чтобы устанавливать тайм-аут на 1000 мс и думать, что он будет вызван (не более) 1 Гц, высокопроизводительные машины будут видеть более быстрое количество кадров (так как единственная фиксированная длительность времени между вызовами DrawVideoFrame()). Я предполагаю, что это характер серфинга асинхронной волны, так сказать.

+1

Я делаю что-то подобное этому в программе, которую я написал некоторое время назад. Если вы хотите приблизиться к 1 Гц, вы можете отслеживать время с момента последнего кадра и соответственно изменять значение таймера. Например, если DrawVideoFrame взял 20 мс, установите таймер на 1000 - 20 до его запуска. Это компенсирует разную скорость/нагрузку на машину в некоторой степени. Это не будет идеально, но он приблизится. –

+0

@WayneTanner: Мне нужно будет пожевать это. Преимущество, по-видимому, является последовательностью. Недостатком является то, что: если это займет больше 1000 мс? Очевидно, вы не можете иметь отрицательное время ожидания. Если вы зажимаете его до> = 0, вы имеете некоторую согласованность, но не обязательно всегда. И если время значительно меняется между кадрами ... все же, я полагаю, это лучше, чем ничего. – micahhoover

+0

Вы правы, это проблема, если ваше время кадра> 1000 мс. Это случилось со мной, и я просто зажал 0 для задержки и приложил все усилия для поддержания целевой частоты кадров. Для того, что я делал, абсолютная частота кадров не была критичной, поэтому она была приемлемой. –

1

Вы видели эту статью http://msdn.microsoft.com/en-us/magazine/jj991977.aspx из выпуска журнала MSDN от марта 2013 года? В первом разделе статьи в какой-то мере рассматриваются обработчики событий async. Это не является прямым решением вашей проблемы, но это может дать вам подсказку.

+0

Спасибо, что поделились, Уэйн. – micahhoover

Смежные вопросы