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

C# WPF使用FileSystemWatcher监听新建XML刷新DataGrid报ArgumentNullException

问题根因排查

  • 你看到的找不到UIElementAutomationPeer.cs提示是Visual Studio调试时缺少框架符号文件导致的,不属于业务代码问题,实际有效异常就是System.ArgumentNullException,由空对象访问触发。
    1. 保存文件的文件名拼接错误:你提供的saveTableToXML方法中,文件路径硬编码为path + "\\.xml",没有拼接选中的ListView项名称,导致新建的文件实际名称为.xml(无主文件名),和你读取时拼接的selectedList.SelectedItem.ToString() + ".xml"完全不匹配。运行时新建文件后读取的是不存在的文件,虽然你捕获了打开文件的异常,但后续defaultData.Tables[0]访问时因为数据集为空,会抛出空参数异常。重启应用后你大概率是手动补了正确命名的文件,所以功能恢复正常。
    1. FileSystemWatcher的Changed事件会被多次触发:文件写入过程中会多次触发Changed事件,此时文件可能还未被写入操作完全释放,就算加了FileShare.ReadWrite也可能读取到不完整的XML内容,导致defaultData.ReadXml加载失败,数据集为空,后续访问Tables[0]抛出异常。
    1. 缺少加载结果校验:读取XML后没有判断defaultData.Tables.Count是否大于0,直接访问Tables[0],一旦读取失败就会抛出空参数异常。
    1. 文件流未使用using自动释放:多处FileStream操作没有用using语法,可能存在资源残留占用,导致后续读写文件失败。
  • 全局定义的FileSystemWatcher不需要刷新配置,只要监听路径正确,运行时新建的xml文件会自动被监听,不需要额外调整。

修复方案

步骤1:修正保存方法的文件名拼接

private void saveTableToXML()
{
    // 先判断是否有选中项,避免空引用
    if (userListView.SelectedItem == null) return;
    DataTable dt = ((DataView)dataGridName.ItemsSource).ToTable();
    // 用Path.Combine拼接路径,避免不同系统的分隔符兼容问题
    string filePath = Path.Combine(path, $"{userListView.SelectedItem.ToString()}.xml");
    try
    {
        // 使用using自动释放文件流,避免资源残留占用
        using FileStream file = File.Create(filePath);  
        dt.WriteXml(file, XmlWriteMode.WriteSchema, false);
    }
    catch(Exception ex)
    {
        MessageBox.Show(ex.Message);
    }
}

步骤2:优化刷新方法,增加空校验

private void refreshDataGrid(DataGrid dataGridName, ListView selectedList, string path)
{
    if (selectedList.SelectedItem == null) return;
    string filePath = Path.Combine(path, $"{selectedList.SelectedItem.ToString()}.xml");
    if (!File.Exists(filePath)) return;
    try
    {
        using FileStream file = File.Open(filePath, FileMode.Open, FileAccess.Read, FileShare.ReadWrite);
        defaultData.Tables.Clear();
        defaultData.ReadXml(file);
        // 新增表存在校验,避免访问空对象
        if (defaultData.Tables.Count > 0)
        {
            dataGridName.ItemsSource = defaultData.Tables[0].DefaultView;
        }
    }
    catch (Exception x)
    {
        MessageBox.Show(x.Message);
    }
}

步骤3:优化FileSystemWatcher触发逻辑,避免重复调用和无效刷新

// 新增防抖锁,避免同一文件多次变更重复触发刷新
private bool _isRefreshing = false;
private void FileWatcher_Changed(object sender, FileSystemEventArgs e)
{
    if (_isRefreshing) return;
    // 只刷新当前选中项对应的文件,避免无关文件变更触发无效刷新
    if (userListView.SelectedItem == null || e.FullPath != Path.Combine(path, $"{userListView.SelectedItem.ToString()}.xml"))
    {
        return;
    }
    _isRefreshing = true;
    Application.Current.Dispatcher.BeginInvoke(System.Windows.Threading.DispatcherPriority.Normal, (Action)(() =>
    {
        try
        {
            // 延迟100ms等待文件写入完成,避免读取到半写入的损坏内容
            Task.Delay(100).Wait();
            refreshDataGrid(dataGridName, userListView, path);
        }
        catch(Exception)
        {
            // 忽略非核心异常
        }
        finally
        {
            _isRefreshing = false;
        }
    }));
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.09 06:39:02