无法将项目MyFile添加或插入到多个位置

4
我正在开发一个应用程序,用于播放Wireshark文件并使用pcapdot.net将数据包发送到网络卡。在我的应用程序中,我获取目录根,并仅添加过去24小时内的新文件。首先,我将目录中的所有文件添加到List<string>中,然后再添加到我的ListView中。现在,在我的应用程序完成播放所有文件后,我想清除我的List、清除我的ListView,并再次搜索最近24小时的新文件并添加到我的ListView中。我的问题出现在这个位置,当我将文件再次添加到我的List并尝试将文件添加到我的ListView时,应用程序会崩溃,并显示错误信息Cannot add or insert the item 'file.pcap' in more than one place. You must first remove it from its current location or clone it.。在播放文件结束后,我清除了List、ListView并再次添加文件以进行播放。
            lvFiles.Items.Clear();
            filesList.RemoveRange(0, filesList.Count - 1);
            addFiles();
            playFiles();

addFiles(); - 将列表中的所有文件添加到我的ListView中:

private void addFiles()
{
    BackgroundWorker backgroundWorker = new BackgroundWorker();
    backgroundWorker.WorkerReportsProgress = true;
    backgroundWorker.DoWork += new DoWorkEventHandler(
    (s3, e3) =>
    {
        filesList = SafeFileEnumerator.EnumerateFiles(pathToSearch, "*.pcap",
            SearchOption.AllDirectories).ToList();
    });

    backgroundWorker.RunWorkerCompleted += new RunWorkerCompletedEventHandler(
        (s3, e3) =>
        {
            if (filesList.Count != 0)
                AddFilesToListView(filesList);
        });

    backgroundWorker.RunWorkerAsync();
}

playFiles() - 播放ListView中的所有文件:

private void playFiles()
{
    lockButtons();
    string filePath = string.Empty;
    BackgroundWorker backgroundWorker = new BackgroundWorker();
    backgroundWorker.WorkerReportsProgress = true;
    backgroundWorker.DoWork += new DoWorkEventHandler(
    (s3, e3) =>
    {
        for (int i = 0; i < lvFiles.Items.Count && shouldContinue; i++)
        {
            this.Invoke((MethodInvoker)delegate
            {
                lvFiles.EnsureVisible(i);
                lvFiles.Items[i].Selected = true;
                lvFiles.Select();
                filePath = lvFiles.Items[i].Tag.ToString();
                toolStripStatusLabel.Text = string.Format("Current file: {0}", lvFiles.Items[i].Text);
            });

            PcapFile pcapFile = new PcapFile();
            pcapFile.sendQueue(filePath, adapter);
            this.Invoke((MethodInvoker)delegate { lvFiles.Items[i].Selected = false; });
        }
    });

将文件添加到我的ListView:

private void addFileToListBox(string filePath, string duration)
{
    item = new ListViewItem(new string[] { new FileInfo(filePath).Name, duration, "Waiting" });
    item.Tag = new FileInfo(filePath).FullName;
    this.Invoke((MethodInvoker)delegate { lvFiles.Items.Add(item); });
}

也许“某人”仍然持有该文件?

展示一些代码。特别是在你向ListView中添加内容和清空ListView时的代码。 - Matt Burland
在addFileToListBox方法中,您在哪里声明名为“item”的ListViewItem? - Mitch
1个回答

3

我很确定这一行代码可能是你的问题所在:

item = new ListViewItem(new string[] { new FileInfo(filePath).Name, duration, "Waiting" });

这将创建一个新的对象,但仍然引用 item,看起来它是在你意图之外的范围内声明的,可能是整个表单。

你需要将对象的作用域变为添加到 ListView 的方法的作用域:

        private void addFileToListBox(string filePath, string duration)
        {
            ListViewItem item = new ListViewItem(new string[] { new FileInfo(filePath).Name, duration, "Waiting" });
            item.Tag = new FileInfo(filePath).FullName;
            this.Invoke((MethodInvoker)delegate { lvFiles.Items.Add(item); });
        }

如果您在更大的范围内声明了变量item,那么每次创建新的ListViewItem时,实际上仍然使用的是列表中的同一个item,就像第一次使用时一样。

虽然您没有展示您在哪里声明了item,但您还需要删除在错误作用域中声明它的行:

ListViewItem item; // <-- Delete me

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接