2015-11-25 3 views
2

Я пишу код для формы, которая должна точно мигать над словом. Он использует «expositionTime» до . Ярлык для X millisececonds и «intervalTime» до скрыть его для Y миллисекунд.C# точно показать ярлык в течение X секунд и скрыть его на Y секунд

Процесс будет повторяться для Z times «numExpositions» и начинается после нажатия кнопки. Мой код работает без ошибок, я использую два таймера для выполнения работы. Проблема в том, что таймеры получают desynchronized после некоторых экспозиций.

Мой вопрос в том, есть ли решение, которое дает мне точную синхронизацию времени, когда время экспозиции (показать ярлык) и интервал (скрыть) начнутся и закончатся вместе - возможно, использование таймеров истекает на отдельных потоках или мониторе, подождите и как реализовать их.

Часть моего кода с помощью двух таймеров:

private System.Windows.Forms.Timer timer1; 
private System.Windows.Forms.Timer timer2; 
private static int counter = 0; 
private static int numExpositions = 16; 
private static int expositionTime = 2000; 
private static int intervalTime = 1800; 

// starts both timers that get desynchronized after some time 
private void button1_Click(object sender, EventArgs e) { startTimer1(); startTimer2(); } 

public void startTimer1() 
{ 
     timer1 = new System.Windows.Forms.Timer() { Interval = expositionTime + intervalTime }; 
     timer1.Tick += new EventHandler(OnTimer1Event); 
     timer1.Start(); 
} 

public void startTimer2() 
{ 
     timer2 = new System.Windows.Forms.Timer() { Interval = intervalTime }; 
     timer2.Tick += new EventHandler(OnTimer2Event); 
     timer2.Start(); 
} 

private void OnTimer1Event(object sender, EventArgs e) 
{ 
    if (counter >= numExpositions) // stops timers 
     { 
      timer1.Stop(); 
      timer2.Stop(); 
      wordLabel.Visible = false; 
      counter = 0; 
      this.Close() 
     } 
     else 
     { 
      wordLabel.Visible = true; // shows wordLabel 
     } 
    } 

private void OnTimer2Event(object sender, EventArgs e) 
{ 
    wordLabel.Visible = false; // hides wordLabel 
} 
+0

Я нахожу вопрос непонятным. Пожалуйста, объясните, почему вы используете два одновременно работающих таймера. Почему бы не просто запустить один таймер, а затем, когда он истек, начните второй? Почему, поскольку интервалы для двух таймеров различны, есть ли у вас какое-то ожидание, что они останутся синхронными даже после одной итерации? Что вы пытались решить, какую проблему вы занимаетесь? Как этот вопрос не дублирует многие существующие вопросы о переполнении стека с таймерами и синхронизацией с часами реального времени? –

+0

'System.Windows.Forms.Timer' не так точны. Если вы хотите, чтобы точность попыталась использовать 'System.Timers.Timer' или' System.Threading.Timer', вы можете найти все различия [здесь] (https://web.archive.org/web/20150329101415/https msdn.microsoft.com/en-us/magazine/cc164015.aspx) – SimpleVar

+0

@SimpleVar: хотя ни один из этих классов таймера не является точным на 100%. Поскольку у всех у них есть контракт, что таймер будет срабатывать не раньше указанного интервала, но, возможно, позже, и поскольку все они подвержены капризам планирования потоков Windows, все они будут иметь схожие неточности. Чтобы быть точным в течение длительного периода времени, код, основанный на сроках, должен учитывать внешние часы (например, часы реального времени компьютера). В качестве альтернативы можно выбрать только один таймер, запустив несколько действий с этого таймера. Это зависит от ситуации. –

ответ

1

лучший способ сделать это, как например:

private async Task DoIt() 
{ 
    for(int i = 0 ; i < numExpositions; i++) 
    { 
     wordLabel.Visible = true; 
     await Task.Delay(expositionTime); //expositionTime is the number of milliseconds to keep the label visible 
     wordLabel.Visible = false; 
     await Task.Delay(intervalTime); //intervalTime is the number of milliseconds to keep the label hidden 
    } 

} 

private void button1_Click(object sender, EventArgs e) 
{ 
    DoIt(); 
} 

Для этого необходимо использовать версию .NET рамочное 4,5 или позже.

+0

Как это связано с трудностями OP в синхронизации _two_ timed мероприятий? –

+0

@PeterDuniho, согласно его первому предложению в вопросе, OP пытается показать ярлык некоторое время, а затем скрыть его некоторое время, и это именно то, что делает этот код.Его попытка использовать двух таймеров не даст ему то, что он хочет, насколько я понимаю его требование. –

+0

С уважением, я не думаю, что вы можете сказать, что пытается сделать OP. Его описание проблемы говорит «после некоторых экспозиций», а не «после одной экспозиции». Таймеры уже не синхронизированы после одной экспозиции, поэтому, если бы это было все, о чем он беспокоился, то это то, что он сказал бы. Понятно, что вы готовы сделать это предположение, но это просто: предположение. Код в вашем ответе фактически не делает то же самое, что и код OP, и OP не ясно, насколько он отличается от поведения, которое у него есть. –

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