You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

.NET6+ WinForms中WebView2遍历ListBox加载网页循环执行问题

解决WebView2循环加载未等待当前流程完成的问题

问题根源

你的代码里用ManualResetEvent配合Task.Run(Sub() resetEvent.WaitOne())会阻塞线程,异步方法里混用同步等待容易导致UI线程卡死或流程混乱;另外Form1_Load中没有等待EnsureCoreWebView2Async完成就直接使用WebView2,可能导致CoreWebView2未初始化完成就绑定事件,引发异常或逻辑错误。

修复方案

用TaskCompletionSource替代ManualResetEvent适配Async/Await异步模式,确保CoreWebView2初始化完成后再执行扫描逻辑,同时实现处理完所有项后从头循环的需求:

Private Async Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
    WebView2 = New WebView2()
    ' 必须等待CoreWebView2初始化完成再进行后续操作
    Await WebView2.EnsureCoreWebView2Async()
End Sub

Private Async Sub scanWeb()
    ' 外层无限循环,处理完所有项后自动重启
    Do
        For Each listBoxElem As String In ListBox1.Items
            ' 用TaskCompletionSource实现异步等待导航完成
            Dim navigationTcs As New TaskCompletionSource(Of Boolean)
            Dim navigationHandler As CoreWebView2NavigationCompletedEventHandler = Nothing

            ' 定义导航完成事件逻辑
            navigationHandler = Sub(sender, e)
                                   ' 导航完成后立即解绑事件,避免内存泄漏
                                   RemoveHandler WebView2.CoreWebView2.NavigationCompleted, navigationHandler
                                   ' 标记任务完成,解除等待
                                   navigationTcs.SetResult(True)
                               End Sub

            AddHandler WebView2.CoreWebView2.NavigationCompleted, navigationHandler
            ' 拼接URL并加载
            WebView2.Source = New Uri($"https://ikalogs.ru/tools/map/?page=1&server=22&world=10&state=active&search=city&allies%5B1%5D=&allies%5B2%5D=&allies%5B3%5D=&allies%5B4%5D=&nick={listBoxElem}&ally=&island=&city=&x=&y=")
            
            ' 等待导航完成后再执行下一步
            Await navigationTcs.Task

            ' 提取页面HTML
            Dim html As String = Await WebView2.ExecuteScriptAsync("document.documentElement.outerHTML;")
            ' 判断结果并添加到DataGridView
            If html.Contains("Not found") Then
                DataGridView1.Rows.Add(listBoxElem, "IN vacanza")
            Else
                DataGridView1.Rows.Add(listBoxElem, "Attivo")
            End If

            ' 可选:添加延迟,避免短时间请求过于频繁触发网站反爬
            Await Task.Delay(600)
        Next

        ' 所有项处理完成后,可选延迟再重启循环
        Await Task.Delay(1500)
    Loop
End Sub

关键修改说明

  • CoreWebView2初始化等待:在窗体加载时必须等待EnsureCoreWebView2Async完成,否则后续操作CoreWebView2会引发异常。
  • TaskCompletionSource替代ManualResetEvent:完全适配Async/Await异步模型,不会阻塞UI线程,确保导航完成后再执行HTML提取逻辑。
  • 事件即时解绑:每次循环创建独立的事件委托,导航完成后立即解绑,避免多次绑定导致逻辑混乱和内存泄漏。
  • 无限循环逻辑:外层Do...Loop实现处理完所有ListBox项后自动从头循环的需求。
  • 请求延迟控制:添加Task.Delay避免短时间内发送过多请求,降低被目标网站限制的风险。

内容的提问来源于stack exchange,提问作者Mattia

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.01 06:02:07