在.NET 6 WPF中异步重试设备初始化直至成功后执行启动方法
.NET 6 WPF 异步重试设备初始化直到成功的最佳实践
你的核心需求是异步执行设备初始化直到成功,同时不阻塞UI线程,原代码的问题在于使用Task.Run(...).Result同步等待结果,会导致UI线程被阻塞,违背了异步的初衷。以下是符合最佳实践的实现方案:
核心优化点
- 用
await替代.Result/.Wait():异步等待线程池任务完成,让UI线程在等待期间可以处理其他交互 - 避免
async void:除事件处理方法外,优先使用async Task,便于异常捕获和流程控制 - 添加重试延迟:避免高频调用初始化方法给设备或系统带来额外负载
优化后的代码示例
SomeDevice _device = new(); // 改用async Task替代async void,规范异步方法定义 public async Task InitAsync() { // 前置初始化代码 bool initSuccess; do { // 异步等待线程池中的初始化操作完成,不阻塞UI线程 initSuccess = await Task.Run(() => _device.Init()); // 初始化失败时,短暂延迟后重试(延迟时间可根据设备特性调整) if (!initSuccess) await Task.Delay(500); } while (!initSuccess); // 初始化成功后执行启动逻辑 await StartAsync(); } public async Task StartAsync() { // 启动前准备代码 // 如果_device.Start()不需要UI线程,直接调用即可 _device.Start(); // 若需在UI线程执行操作(如更新UI控件),使用异步版Dispatcher调用 await Application.Current.Dispatcher.InvokeAsync(() => { // 这里放置必须在UI线程执行的逻辑 // 例如:statusLabel.Content = "设备已启动"; }); }
进阶:添加取消支持
如果需要允许用户中途取消初始化流程,可以引入CancellationToken:
public async Task InitAsync(CancellationToken cancellationToken) { bool initSuccess; do { // 检查是否触发取消请求 cancellationToken.ThrowIfCancellationRequested(); initSuccess = await Task.Run(() => _device.Init(), cancellationToken); if (!initSuccess) await Task.Delay(500, cancellationToken); } while (!initSuccess); await StartAsync(); }
内容的提问来源于stack exchange,提问作者Tiran
相关产品推荐
相关产品推荐

