.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
相关产品推荐
相关产品推荐

