我試圖使用this FAQ中描述的取消令牌。這是我最初的想法:使用異步任務取消任務
private async void OnLoginButtonClicked(object sender, EventArgs e)
{
if (this.cancelToken == null)
{
this.cancelToken = new CancellationTokenSource();
}
try
{
bool loginSuccess = await AsyncLoginTask(this.cancelToken.Token);
if (loginSuccess)
{
// Show main page
}
}
catch (OperationCanceledException ex)
{
System.Diagnostics.Debug.WriteLine(ex.Message);
}
catch (Exception ex)
{
System.Diagnostics.Debug.WriteLine(ex.Message);
}
finally
{
this.cancelToken = null;
}
}
private async Task<bool> AsyncLoginTask(CancellationToken cancellationToken = default(CancellationToken))
{
// Pass the token to HttpClient()
}
現在我適應它,這就是結果:
private async void OnLoginButtonClicked(object sender, EventArgs e)
{
this.cancelToken?.Dispose();
this.cancelToken = new CancellationTokenSource();
try
{
var ui = TaskScheduler.FromCurrentSynchronizationContext();
var loginTask = Task.Factory.StartNew(async() =>
{
bool loginSuccess = await AsyncLoginTask(this.cancelToken.Token);
}, this.cancelToken.Token);
var displayResults = loginTask.ContinueWith(resultTask =>
{
// How do I know if the login was successful?
// Because AsyncLoginTask() returns bool.
System.Diagnostics.Debug.WriteLine("done");
},
CancellationToken.None,
TaskContinuationOptions.OnlyOnRanToCompletion,
ui);
var displayCancelledTasks = loginTask.ContinueWith(resultTask =>
{
System.Diagnostics.Debug.WriteLine("canceled");
},
CancellationToken.None,
TaskContinuationOptions.OnlyOnCanceled, ui);
}
catch (Exception ex)
{
System.Diagnostics.Debug.WriteLine(ex.Message);
}
}
問題:
- 我怎麼知道,如果登錄成功?因爲
AsyncLoginTask()
返回bool
。 - 如何正確創建和銷燬令牌以允許多次啓動和取消操作?
- 如何處理任務中的任務? 「完成」顯示在控制檯中,而任務(AsyncLoginTask)尚未完成。
'我怎麼知道,如果登錄成功?因爲AsyncLoginTask()返回bool,所以你可以在該任務中返回'loginSuccess',這會給'loginTask'一個結果。但是......我的問題在於,你爲什麼要在任務中包裝你的登錄任務? – Stefan
我的舊代碼('AsyncLoginTask')是以這種方式構建的(async/await,返回true/false)。現在我想讓用戶可以取消操作。在鏈接的文章中,推薦使用「ContinueWith」任務。所以我包裝了我的任務。我應該繼續捕捉'OperationCanceledException'嗎? – testing
那麼,我還沒有深入的鏈接文章,我必須說我不是這方面的專家......但是,由於登錄已經有一個選項提供取消令牌,並在稍後的邏輯需要登錄結果,一個簡單的'await'對我來說似乎更直觀。你可以用適當的方式處理這個取消。你能解釋你的實際目標嗎?爲什麼你認爲這個重構將有助於實現它? – Stefan