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

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.04 12:47:15