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

C# WPF应用运行时修改DataTable抛出System.ArgumentOutOfRangeException异常求助

问题根因

你的错误本质是DataTable多线程操作不安全+定时器重入,和行数正相关的报错延迟也完全匹配这个根因:

  • 你用Task.Run把ProcessToastMessages放到后台线程执行,同时DataTable绑定了UI的DataGrid,UI线程本身也会随时读取DataTable的状态;
  • 定时器间隔为10秒,当DataTable行数较多时,逐行Ping的总耗时很容易超过10秒,导致上一次任务还没跑完,下一次定时器触发又启动了一个新的后台任务,多个线程同时读写同一个DataTable,行计数状态会出现紊乱;
  • 你提前缓存了rowCount = ds.Tables[0].Rows.Count作为遍历边界,但遍历过程中如果DataTable行数被其他线程修改(新增/删除),缓存的计数和实际行数不一致,就会触发索引越界。

修复方案

1. 阻止定时器任务重入

加运行状态标志,确保同一时间只有一个ProcessToastMessages在执行:

private bool _isProcessing = false;
private async void timer_Tick(object sender, EventArgs e)
{
    // 上一次任务未执行完直接跳过本次
    if (_isProcessing) return;
    _isProcessing = true;
    try
    {
        await Task.Run(() => ProcessToastMessages());
    }
    finally
    {
        _isProcessing = false;
    }
}

2. 安全遍历DataTable

不要提前缓存行数,遍历前先给当前DataTable的行拍快照,避免遍历过程中行数变化导致越界:

private void ProcessToastMessages()
{
    WindowsToasts.WindowsToast windowsUpdateToast = new WindowsToast();
    // 拍行快照,后续遍历快照不受DataTable实时变化影响
    var rows = ds.Tables[0].Rows.Cast<DataRow>().ToList();
    foreach (var row in rows)
    {
        DateTime scheduledTime = DateTime.Now;
        DateTime.TryParse(row["schedule"].ToString(), out scheduledTime);
        string currentStatus = row["status"].ToString();
        if ((scheduledTime.Ticks < DateTime.Now.Ticks) && currentStatus == "Pending")
        {
            string computerName = row["hostname"].ToString();
            bool isOnline = ComputerFuncs.ComputerOnline(computerName);
            // DataTable绑定了UI控件,修改操作要调度到UI线程执行,避免跨线程访问异常
            Application.Current.Dispatcher.Invoke(() =>
            {
                if (isOnline)
                {
                    row.SetField("online", true);
                    row.SetField("status", "Sent");
                }
                else
                {
                    row.SetField("online", false);
                }
            });
        }
    }
}

3. 额外优化建议

可以把同步Ping替换为异步Ping方法,减少线程阻塞时间,进一步降低任务超时重入的概率。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.26 13:45:06