您必须正确等待异步方法。当您调用
Task.Result
时,异步方法将同步执行,因为当前线程正在等待 Result
属性返回。总是 await
async
方法。
你的代码看起来也很臭。不应涉及任何静态属性或实例。您没有提供足够的上下文来理解您在做什么。
class MainWindow : Window
{
public static HttpClient SharedHttpClient { get; }
= new HttpClient();
private CancellationTokenSource HttpClientCancellationTokenSource { get; set; }
private async Task UploadAsync(HttpContent content)
{
try
{
// CancellationTokenSource implements IDisposable!
// We must dispose it e.g. via the using statement/expression or a finally block or explicitly.
using this.HttpClientCancellationTokenSource = new CancellationTokenSource();
string url = GetFileRequestUrl();
// await the async method. Now the user can click the button and execute the cancel operation
// *while* the upload is running.
await MainWindow.SharedHttpClient.PostAsync(url, content, this.HttpClientCancellationTokenSource.Token);
}
catch(OperationCanceledException)
{
// Somebody has cancelled the async task.
// TODO::Perform rollback, cleanup etc.
// To allow the caller of this operation to handle cancellation too
// you can rethrow the exception or swallow it
//throw;
}
finally
{
// this.HttpClientCancellationTokenSource is already disposed at this point (using expression).
// Set variable to NULL so nobody can accidently try to use the disposed instance
this.HttpClientCancellationTokenSource = null;
}
}
private async void CancelUpload_OnClick(object sender, RoutedEventArgs e)
=> this.HttpClientCancellationTokenSource?.Cancel();
}