2013-03-25 45 views
10

我有這種方法播放聲音,當用戶點擊屏幕時,我想讓它在用戶再次點擊屏幕時停止播放。但問題是「DoSomething()」方法並沒有停止,它一直持續到它完成。只需停止異步方法

bool keepdoing = true; 

private async void ScreenTap(object sender, System.Windows.Input.GestureEventArgs e) 
    { 
     keepdoing = !keepdoing; 
     if (!playing) { DoSomething(); } 
    } 

private async void DoSomething() 
    { 
     playing = true; 
     for (int i = 0; keepdoing ; count++) 
     { 
      await doingsomething(text); 
     } 
     playing = false; 
    } 

任何幫助將不勝感激。
謝謝:)

+0

嘗試宣告'keepdoing'爲'揮發性布爾keepdoing = TRUE;'但是,如果'doingsomething'時間太長,返回,用戶可以按屏幕兩次從而觸發'keepdoing'假,回到真實。 – 2013-03-25 12:45:36

+0

doingsomething不需要很長時間,但由於循環,Dosomething()需要時間。我很抱歉地說,但波動不起作用。 – Jaydeep 2013-03-25 12:46:53

+0

易失性不是問題,因爲await之後的代碼總是被分派回UI線程......它不是一個同步問題。 – 2015-07-27 12:00:03

回答

23

這是CancellationToken的用途。

CancellationTokenSource cts; 

private async void ScreenTap(object sender, System.Windows.Input.GestureEventArgs e) 
{ 
    if (cts == null) 
    { 
    cts = new CancellationTokenSource(); 
    try 
    { 
     await DoSomethingAsync(cts.Token); 
    } 
    catch (OperationCanceledException) 
    { 
    } 
    finally 
    { 
     cts = null; 
    } 
    } 
    else 
    { 
    cts.Cancel(); 
    cts = null; 
    } 
} 

private async Task DoSomethingAsync(CancellationToken token) 
{ 
    playing = true; 
    for (int i = 0; ; count++) 
    { 
    token.ThrowIfCancellationRequested(); 
    await doingsomethingAsync(text, token); 
    } 
    playing = false; 
} 
+1

是否應該有'finally'將'cts'設置爲'null'?完成(未取消)運行後,需要2次輕敲才能運行「DoSomethingAsync」。 – Gusdor 2015-03-13 10:39:35

+0

@Gusdor:趕上!我修復了一下。這不是很好* - CTS可以被重用,而不僅僅是GCed,但是它得到了普遍的觀點。 – 2015-03-13 12:03:03