2017-01-19 38 views
0

我在C#中有一個異步調用,我試圖實現取消邏輯。我在互聯網上搜索,但我找不到解決我的問題。在C#中取消異步和等待方法#

我有一個Windows窗體與開始按鈕,取消按鈕和文本框來顯示結果。以下代碼:

private CancellationTokenSource _cancelSource; 
private CancellationToken _token; 

private void btnStart_Click(object sender, EventArgs e) 
{ 
    DisplayPrimeCountsAsync(_token); 
} 

private async void DisplayPrimeCountsAsync(CancellationToken token) 
{ 
    btnStart.Enabled = false; 

    for (int i = 0; i < 100; i++) 
    { 
    textBox1.Text += await GetPrimesCountAsync(i*1000000 + 2, 1000000, token) + Environment.NewLine; 
    } 

    btnStart.Enabled = true; 
} 

private Task<int> GetPrimesCountAsync(int start, int count, CancellationToken token) 
{ 
    return 
     Task.Run(() => 
      ParallelEnumerable.Range(start, count).Count(n => 
       Enumerable.Range(2, (int) Math.Sqrt(n) - 1).All(i => n%i > 0)), token); 
    } 

private void btnCancel_Click(object sender, EventArgs e) 
{ 
    _cancelSource = new CancellationTokenSource(); 
    _token = _cancelSource.Token; 
    _cancelSource.Cancel(); 
    btnCancel.Enabled = false; 
} 

現在這根本不會被取消。我發現下面的代碼段:

if (token.IsCancellationRequested) 
{ 
    token.ThrowIfCancellationRequested(); 
} 

,但我不知道在哪裏把這個試圖把這個和素數LINQ表達成另一種方法和調用此方法在Task.Run但沒有。幫助。有人能告訴我如何以正確的方式實施這種取消邏輯嗎? 在此先感謝!

+0

您是否嘗試過這段代碼? – EpicKip

回答

2

您是否嘗試在啓動任務之前調用以下代碼?

_cancelSource = new CancellationTokenSource(); 
_token = _cancelSource.Token; 

感覺就像您啓動任務時令牌爲空,然後您設置它。 (雖然沒有嘗試)

當然在這種情況下,你必須從你的取消方法中刪除相同的代碼。

+0

這是解決方案。非常感謝你!我能以某種方式處理上面的取消代碼中的異常嗎? – Canox

+0

對不起,我不明白你想要做什麼這個例外。 –

+0

沒關係。我明白了:)感謝您的幫助!我將帶有await語句的代碼放在try - catch塊中,並將TaskCancelledException轉換爲MessageBox,然後使用return語句跳出代碼 – Canox