求助:等待await返回True的优化方案,替代Thread.Sleep避免阻塞
优化VB.NET异步加载后的等待逻辑
问题核心
原来用while循环+Thread.Sleep的方式,不仅会阻塞异步线程,固定循环次数还没法保证加载完成,甚至可能导致程序永久挂起。下面给几个更合理的异步友好方案:
方案1:用TaskCompletionSource实现精准异步等待
这是最推荐的方式,让加载方法完成时主动发出信号,我们用await等待信号,完全不阻塞线程,还能加超时保护。
' 定义一个TaskCompletionSource来追踪加载完成状态 Private tcsShopifyLoaded As TaskCompletionSource(Of Boolean) Private Async Sub YourEntryMethod() ' 初始化信号源 tcsShopifyLoaded = New TaskCompletionSource(Of Boolean)() ' 启动异步加载 Await LoadShopifyProducts() Try ' 等待加载完成,最多等30秒(可按需调整) If Await tcsShopifyLoaded.Task.WaitAsync(TimeSpan.FromSeconds(30)) Then Button1.PerformClick() Else MessageBox.Show("产品加载超时,请重试") End If Catch ex As Exception MessageBox.Show($"加载失败:{ex.Message}") End Try End Sub ' 改造LoadShopifyProducts方法,完成时触发信号 Private Async Function LoadShopifyProducts() As Task ' 原有Shopify产品加载逻辑,比如调用API Await FetchProductsFromShopifyApi() ' 加载完成后更新状态并触发信号 LoadedShopifyProducts = True tcsShopifyLoaded.SetResult(True) End Function
方案2:异步轮询(不修改原有加载方法)
如果没法改LoadShopifyProducts,就把Thread.Sleep换成Task.Delay,异步等待不会阻塞线程,再加上超时判断避免无限循环:
Private Async Sub YourEntryMethod() Await LoadShopifyProducts() Dim maxWaitTime = TimeSpan.FromSeconds(30) Dim startWaitTime = DateTime.Now ' 异步循环检查状态 While Not LoadedShopifyProducts ' 超时就退出 If DateTime.Now - startWaitTime > maxWaitTime Then MessageBox.Show("产品加载超时") Return End If ' 异步等待100ms,不阻塞线程 Await Task.Delay(100) End While ' 状态满足后执行点击 Button1.PerformClick() End Sub
方案3:用属性变更事件实现无轮询等待
如果LoadedShopifyProducts是可以修改的变量,改成带变更事件的属性,用事件通知代替轮询,效率更高:
' 把变量改成带事件的属性 Private _loadedShopifyProducts As Boolean Public Property LoadedShopifyProducts As Boolean Get Return _loadedShopifyProducts End Get Set(value As Boolean) _loadedShopifyProducts = value ' 状态变化时触发事件 RaiseEvent LoadedShopifyProductsChanged(Me, EventArgs.Empty) End Set End Property Public Event LoadedShopifyProductsChanged As EventHandler Private Async Sub YourEntryMethod() Await LoadShopifyProducts() Using cts = New CancellationTokenSource(TimeSpan.FromSeconds(30)) Try ' 等待属性变更事件触发 Await Task.FromEvent( Sub(handler) AddHandler LoadedShopifyProductsChanged, handler, Sub(handler) RemoveHandler LoadedShopifyProductsChanged, handler ).WaitAsync(cts.Token) Button1.PerformClick() Catch ex As OperationCanceledException MessageBox.Show("加载超时") End Try End Using End Sub
内容的提问来源于stack exchange,提问作者BASit Bulbulia
相关产品推荐
相关产品推荐

