2013-03-25 10 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 = trueとkeepdoing'; 'しかしdoingsomething'を返すために時間がかかりすぎる'場合は、ユーザが画面を二回、それによってfalseに 'keepdoing'を切り替え、バックtrueに押すことができます。 –

+0

doingsomethingは時間がかかりませんが、ループのためにDosomething()に時間がかかります。 &申し訳ありませんが、揮発性は機能しませんでした。 – Jaydeep

+0

揮発性は問題ではありません。なぜなら、待機した後のコードは常にUIスレッドに返されるからです。同期の問題ではありません。 –

答えて

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

'cts'を' null'に設定する 'finally'ブロックがありますか?完全な(キャンセルされていない)実行の後、 'DoSomethingAsync'を実行するには2回のタップが必要です。 – Gusdor

+0

@Gusdor:良いキャッチ!私は修正で編集しました。 * CTSはGCedの代わりに再利用することができますが、一般的な点が得られます。 –

関連する問題