BackgroundWorker未工作却提示繁忙的异常问题求助
BackgroundWorker触发异常排查思路
我在桌面应用窗体中使用BackgroundWorker从互联网加载数据时遇到异常:点击单选按钮RdMain触发BGW可正常运行,但点击另一单选按钮RdSub(代码与RdMain完全一致)时,BGW明明未工作却弹出「当前繁忙」的错误提示。
触发代码
RdMain的CheckedChanged事件:
private void RdMain_CheckedChanged(object sender, EventArgs e) { if (BgwCodeLevel.IsBusy) { BgwCodeLevel.CancelAsync(); } xAccounts.xClsMain.ShowPB(); BgwCodeLevel.RunWorkerAsync(); }
RdSub的CheckedChanged事件代码与上述完全一致。
BackgroundWorker核心代码
DoWork方法:
private void BgwCodeLevel_DoWork(object sender, DoWorkEventArgs e) { try { //CheckConn if (xAccounts.xClsDb.CheckConn() == false) { Settings.Default.ErrType = 1; return; } //Get Code + Level xAccounts.AccParent = Convert.ToInt64(CboAccParent.SelectedValue); if (RdMain.Checked) { xAccounts.AccType = "main"; } else { xAccounts.AccType = "sub"; } xAccounts.Get_AccCode(); xAccounts.Get_AccLevel(); Settings.Default.ErrType = 0; } catch { Settings.Default.ErrType = 2; } finally { xAccounts.xClsDb.CloseConn(); } }
RunWorkerCompleted方法:
//End private void BgwCodeLevel_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e) { switch (Settings.Default.ErrType) { case 0: TxtAccCode.Text = xAccounts.AccCode.ToString(); TxtAccLevel.Text = xAccounts.AccLevel.ToString(); xAccounts.xClsMain.HidePB(); break; case 1: xAccounts.xClsMain.Msg_ErrCon(); break; case 2: xAccounts.xClsMain.Msg_ErrOp(); break; case 3: xAccounts.xClsMain.Msg_ErrDbl(); break; } }
排查思路
- 检查CheckedChanged事件触发逻辑:单选按钮的
CheckedChanged事件会在选中和取消选中时双向触发。点击RdSub时,RdMain会从选中变为未选中,触发RdMain的事件;紧接着RdSub的事件也会触发,两次事件的执行可能导致BGW的IsBusy状态判断冲突。 - 验证事件触发顺序与BGW状态:在两个CheckedChanged事件中添加调试日志(如
Debug.WriteLine($"RdMain触发,IsBusy={BgwCodeLevel.IsBusy}")),确认点击RdSub时的事件触发顺序和BGW的实时状态,排查是否是连续调用RunWorkerAsync导致的冲突。 - 完善CancelAsync后的等待逻辑:
CancelAsync仅发送取消信号,BGW不会立即停止。需要在调用CancelAsync后,等待BGW完成(比如通过循环检查IsBusy并配合Thread.Sleep(100),或使用同步事件),再调用RunWorkerAsync,避免并发触发。 - 增加DoWork中的取消响应:当前DoWork方法未检查
CancellationPending属性,导致BGW无法及时响应取消请求,IsBusy会一直为true。在DoWork的关键步骤(如数据库操作前后)加入判断:if (BgwCodeLevel.CancellationPending) { e.Cancel = true; return; } - 排查共享变量的线程安全:
xAccounts是UI线程和BGW线程共享的对象,多线程访问可能导致状态异常。对xAccounts的读写操作添加锁(如lock(xAccounts)),或确保UI线程在BGW运行时不修改相关变量。 - 确认RunWorkerCompleted的完整性:检查
RunWorkerCompleted是否每次都能正常执行,比如是否存在未捕获的异常导致HidePB或状态重置失败,进而影响BGW的状态判断。
内容的提问来源于stack exchange,提问作者Hamada
相关产品推荐
相关产品推荐

