using System.Net.Http;
using System.Threading;
using System.Threading.Tasks;
namespace BlazorAppJavaScript.Components.Pages
{
public partial class CounterAsync : IAsyncDisposable
{
private CancellationTokenSource? _cts;
private bool _disposed = false;
// 文件下载方法,支持取消
private async Task DownloadFileAsync(string url)
{
_cts = new CancellationTokenSource();
try
{
using var httpClient = new HttpClient();
var response = await httpClient.GetAsync(url, _cts.Token);
response.EnsureSuccessStatusCode();
var content = await response.Content.ReadAsByteArrayAsync(_cts.Token);
// 处理下载内容
}
catch (OperationCanceledException)
{
// 下载被取消
}
}
// 页面关闭时取消下载
protected virtual async ValueTask DisposeAsyncCore()
{
if (_cts != null)
{
_cts.Cancel();
_cts.Dispose();
_cts = null;
}
await Task.CompletedTask;
}
public async ValueTask DisposeAsync()
{
if (!_disposed)
{
await DisposeAsyncCore();
_disposed = true;
GC.SuppressFinalize(this);
}
}
}
}
/*ValueTask 和 Task 都用于表示异步操作,但它们有以下主要区别:
1. 内存分配
• Task:每次异步方法返回 Task 时,都会分配一个对象(即使结果已完成)。
• ValueTask:是一个结构体(struct),可以避免不必要的堆分配,尤其是在结果已完成或同步可用时。
2. 使用场景
• Task:适用于大多数异步场景,推荐作为标准返回类型。
• ValueTask:适合高性能场景,比如结果经常是同步完成的(如缓存命中),可以减少对象分配。
3. 多次等待
• Task:可以多次 await 或注册回调。
• ValueTask:只能 await 一次,不能多次等待或注册多个回调,否则行为未定义。
4. API 兼容性
• Task:与大多数异步 API 兼容。
• ValueTask:部分 API 不支持,使用时需注意兼容性。
public async Task<int> GetValueAsync() { ... } // 标准用法
public async ValueTask<int> GetValueAsync() { ... } // 高性能场景
*/