2013-12-14 3 views
0

Мне нужно сохранить продолжительность фортепиано с помощью Ticks, чтобы затем сделать показ нот в соответствии с этой продолжительностью (музыкальные игроки узнают).C# Таймер не сбрасывается с одного щелчка мыши на другой

Я использую интервал 100, но в течение некоторого тестирования я использовал его на 1000.

Проблема заключается в следующем. Когда я вызываю метод (я беру 1000 миллисекундный интервал один) таймер запускается. Если мне НЕ удастся получить 1000 миллисекунд, это показывает Длительность 0: но тогда, если я делаю, например, 2 секунды, он показывает 3 секунды, если я попытаюсь нажать его еще на секунду (другая клавиша), он будет показывать 4 секунды вместо 1.

Как будто он продолжает повторяться. То же самое произошло с 100 интервалом один. Это сошло с ума. иногда 40 иногда 23 и так далее. Любая идея, как это исправить (сброс таймера)

NB Я использую System.Windows.Forms.Timer в библиотеке

часть метода, который вызывает методы ниже

for (int i = 0; i < 15; i++) 
{ 
    WhiteKey wk = new WhiteKey(wKeys[i], wPos[i]-35,0); //create a new white Key with [i] Pitch, at that x position and at y =0 position 
    wk.MouseDown += onRightClick; //holds the Duration on Right Click 
    wk.MouseUp += onMouseUp; 
    wk.Click += new EventHandler(KeyClick); //Go to KeyClick Method whenever a key is pressed 
    this.panel1.Controls.Add(wk); //Give it control (to play and edit) 
} 

Методы управления временем

private void onRightClick(object sender, MouseEventArgs e) 
{   
    wk = sender as WhiteKey; 
    duration = 0; 
    t1.Enabled = true; 
    t1.Tick += timeTick; 
    t1.Interval = 100; 
} 

private void timeTick(object sender, EventArgs e) 
{ 
    duration++; 
} 

private void onMouseUp (object sender, MouseEventArgs e) 
{ 

    t1.Enabled = false; 
    String time = "Key: " + pitch + "\nDuration: " +duration ; //Test purposes to see if timer works 
    MessageBox.Show(time); 
} 

ответ

1

Вы пытаетесь измерить время, не используйте таймер, используйте Stopwatch.

Вы можете найти C# Stopwatch Exmples at dotnetpearls.com.

В абстрактных это то, что вы хотели бы сделать что-то вроде этого:

private void onRightClick(object sender, MouseEventArgs e) 
{ 
    stopwatch.Reset(); 
    stopwatch.Start(); 
} 

private void onMouseUp (object sender, MouseEventArgs e) 
{ 
    stopwatch.Stop(); 
    String msg = "Duration in seconds: " + (stopwatch.ElapsedMilliseconds/1000.0).ToString("0.00"); 
    MessageBox.Show(msg); 
} 

Примечание: Вы можете изменить единицы или формат строки.


Примечание по использованию таймера:

1) System.Windows.Forms.Timer использует цикл обработки сообщений из окна, это означает, что она может быть отсрочена, потому что окно занято обработкой других событий (например как клик). Для лучшего поведения используйте System.Threading.Timer.

2) Если вы используете System.Windows.Forms.Timer, не устанавливайте обработчик события Tick каждый клик. Обработчик события будет выполняться один раз для каждого его добавления.

То есть:

private void onRightClick(object sender, MouseEventArgs e) 
{   
    wk = sender as WhiteKey; 
    duration = 0; 
    t1.Enabled = true; 
    //t1.Tick += timeTick; you should add this only once not each click 
    t1.Interval = 100; 
} 

3) Если вы используете System.Threading.Timer вы можете сделать переменную durationvolatile.

+0

Я попробовал STOPWATCH, работал как шарм. Спасибо. Я также увижу второй метод таймера. Большое спасибо за вашу помощь. – DodoSerebro

+0

Другое дело. Windows.Timers.TIMER - как он обрабатывает TICKS, поскольку на самом деле он не имеет его в своей библиотеке? – DodoSerebro

+1

@DodoSerebro Timer.Tick - это событие. Internal Timer хранит список методов, которые он должен вызывать каждый «тик». Когда вы говорите 't1.Tick + = timeTick', вы говорите:« Я хочу, чтобы вы вызывали timeTick каждый раз, когда событие Tick срабатывает ». Теперь событие Tick работает, сообщая ОС о выпуске сообщения с заданным интервалом (в Windows это WM_TIMER, см. [SetTimer] (http://msdn.microsoft.com/en-us/library/windows/desktop /ms644906(v=vs.85).aspx)), каждый раз, когда окно получает это сообщение, он запускает специальную функцию, обрабатываемую объектом Timer, которая в свою очередь вызовет все методы в его списке. – Theraot

1
t1.Tick += timeTick; 

Кстати, в вашем примере кода вы каждый раз подписываетесь на событие таймера «Tick» каждый раз щелчком правой кнопки мыши. Итак, если вы нажмете 2 раза метод

private void timeTick(object sender, EventArgs e) 

будет называться дважды, и "продолжительность ++ будет выполняться дважды. Код подписки на событие должен выполняться только один раз для таймера. P.S.Если вам нужно измерить продолжительность, таймер не лучший способ сделать это.

+0

Итак, в этом случае, если я использую t1.Tick + = time Tick .., где это должно быть точно? Вне метода onRightClick? – DodoSerebro

+1

Да. Вы можете установить его сразу после создания экземпляра t1. –

+0

Спасибо, попробуем это на всякий случай, хотя секундомер работает отлично :) Еще раз спасибо за вашу помощь! – DodoSerebro

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