2014-02-02 2 views
0

Это игра: пользователь может навешивать несколько элементов, но только если мышь остается там более 500 мс, вызывается функция. Если пользователь перемещает мышь над другим элементом, обратный отсчет с 500 мс перезапускается. Но, если пользователь нажимает обратный отсчет элемента, он останавливается, пока не будет виден другой элемент.Подождите 500 мс для ввода пользователем с возможностью отмены или перезапуска

Это моя попытка, но BackgroundWorker не может быть перезапущен, так как аннулирование отменено.

public BackgroundWorker bw = new BackgroundWorker(); 
private void Element_MouseEnter(object sender, MouseEventArgs e) 
{ 
    bw.DoWork += (snd, args) => 
    { 
    int i = 500; //500ms 
    while (i > 0) 
    { 
     if (bw.CancellationPending) break; 
     Thread.Sleep(10); 
     i = i - 10; 
    }    
    }; 
    bw.RunWorkerCompleted += (snd, args) => 
    { 
    RunSomething(); //500 ms are out, nothing was clicked 
    } 
    if (bw.IsBusy) bw.CancelAsync(); 
    bw.RunWorkerAsync(); 
} 

private void Element_Clicked(object sender, MouseEventArgs e) 
{ 
    bw.CancelAsync(); 
} 

Там должно быть лучше ...

+0

500 миллисекунд равна half-second.How вы проверить его и выяснить это не отменяя? –

+2

Используйте параллельную библиотеку задач и передайте токен отмены на task.delay –

ответ

3
private CancellationTokenSource tokenSource; 

private async void button1_MouseEnter(object sender, EventArgs e) 
{ 
    if (tokenSource != null) 
     tokenSource.Cancel(); 

    tokenSource = new CancellationTokenSource(); 
    try 
    { 
     await Task.Delay(500, tokenSource.Token); 
     if (!tokenSource.IsCancellationRequested) 
     { 
      // 
     } 
    } 
    catch (TaskCanceledException ex) { } 
} 

private void button1_Click(object sender, EventArgs e) 
{ 
    tokenSource.Cancel(); 
} 
+0

Блестящий! Чистый и простой. Большое вам спасибо! – Daniel

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