首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >是否通过线程将文件添加到列表框?

是否通过线程将文件添加到列表框?
EN

Stack Overflow用户
提问于 2012-12-13 04:14:31
回答 2查看 391关注 0票数 0

在我的应用程序中,我想将文件添加到我的列表框中。如果我的文件不是pcap扩展名,我希望将文件路径发送到我的类,并将其转换为pcap扩展名,然后将此文件添加到我的列表框中。如果我选择添加namy文件,GUI直到我的应用程序完成添加或转换这个文件时才响应,我想知道如何添加通过线程完成这一切的选项。

代码语言:javascript
复制
private void btnAddfiles_Click(object sender, EventArgs e)
{
    System.IO.Stream stream;
    OpenFileDialog thisDialog = new OpenFileDialog();
    thisDialog.InitialDirectory = (lastPath.Length > 0 ? lastPath : "c:\\");
    thisDialog.Filter = "(*.snoop, *.pcap, *.cap, *.net, *.pcapng, *.5vw, *.bfr, *.erf, *.tr1)" +
        "|*.snoop; *.pcap; *.cap; *.net; *.pcapng; *.5vw; *.bfr; *.erf; *.tr1|" + "All files (*.*)|*.*";
    thisDialog.FilterIndex = 1;
    thisDialog.RestoreDirectory = false;
    thisDialog.Multiselect = true;
    thisDialog.Title = "Please Select Source File";

    if (thisDialog.ShowDialog() == DialogResult.OK)
    {
        if (thisDialog.FileNames.Length > 0)
        {
            lastPath = Path.GetDirectoryName(thisDialog.FileNames[0]);
        }

        foreach (String file in thisDialog.FileNames)
        {
            try
            {
                if ((stream = thisDialog.OpenFile()) != null)
                {
                    using (stream)
                    {
                        string fileToAdd = string.Empty;
                        Editcap editcap = new Editcap();


                            BackgroundWorker backgroundWorker = new BackgroundWorker();
                            backgroundWorker.WorkerReportsProgress = true;
                            backgroundWorker.DoWork += new DoWorkEventHandler(
                            (s3, e3) =>
                            {
                                if (!editcap.isLibpcapFormat(file))
                                {
                                    fileToAdd = editcap.getNewFileName(file);
                                }
                                else
                                {
                                    listBoxFiles.Items.Add(file);
                                }
                            });

                            backgroundWorker.RunWorkerCompleted += new RunWorkerCompletedEventHandler(
                                (s3, e3) =>
                                {
                                    listBoxFiles.Items.Add(fileToAdd);
                                });

                            backgroundWorker.RunWorkerAsync();

                        lastPath = Path.GetDirectoryName(thisDialog.FileNames[0]);
                    }
                }
            }

            catch (Exception ex)
            {
                MessageBox.Show("Error: Could not read file from disk. Original error: " + ex.Message);
            }
        }

    }
}
EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2012-12-13 04:27:06

您的应用程序正在冻结,因为您在UI线程中执行了大量工作。您需要将长时间运行的任务移动到后台线程,然后只需更新UI线程中的UI。

为此,您需要做的第一件事是将长时间运行的任务从UI操作中分离出来。目前,您正在将这两者混合在一起,这就是导致您对如何将其映射到BackgroundWorker感到困惑的原因。

只要不需要迭代地更新列表框,并且可以一次性添加列表末尾的所有项(这就是我对列表框的期望),您就可以简单地在一个地方执行文件IO,将结果添加到某种类型的集合中(List在这里可能比较合适),然后,可以将列表中的所有项分别添加到ListBox中(或使用数据绑定)。

一旦你做了改变,使用像BackgroundWorker这样的东西就很容易了。填充List的IO工作在DoWork中进行,在后台运行,然后设置Result。然后,RunWorkerCompleted事件获取该列表并将这些项添加到ListBox中。

如果你迫切需要在列表框中添加项目,因此随着时间的推移,你会看到一个项目,然后是下一个项目,等等,那么只需将其视为“报告进度”,并使用BackgroundWorker中内置的相关进度报告功能。在循环中更新进度,并在进度报告事件处理程序中获取给定的值并将其放入ListBox中。

下面是一个实现:

代码语言:javascript
复制
private void btnAddfiles_Click(object sender, EventArgs e)
{
    System.IO.Stream stream;
    OpenFileDialog thisDialog = new OpenFileDialog();
    thisDialog.InitialDirectory = (lastPath.Length > 0 ? lastPath : "c:\\");
    thisDialog.Filter = "(*.snoop, *.pcap, *.cap, *.net, *.pcapng, *.5vw, *.bfr, *.erf, *.tr1)" +
        "|*.snoop; *.pcap; *.cap; *.net; *.pcapng; *.5vw; *.bfr; *.erf; *.tr1|" + "All files (*.*)|*.*";
    thisDialog.FilterIndex = 1;
    thisDialog.RestoreDirectory = false;
    thisDialog.Multiselect = true;
    thisDialog.Title = "Please Select Source File";

    if (thisDialog.ShowDialog() == DialogResult.OK)
    {
        if (thisDialog.FileNames.Length > 0)
        {
            lastPath = Path.GetDirectoryName(thisDialog.FileNames[0]);
        }

        BackgroundWorker backgroundWorker = new BackgroundWorker();
        backgroundWorker.WorkerReportsProgress = true;
        backgroundWorker.DoWork +=
        (s3, e3) =>
        {
            //TODO consider moving everything inside of the `DoWork` handler to another method
            //it's a bit long for an anonymous method
            foreach (String file in thisDialog.FileNames)
            {
                try
                {
                    if ((stream = thisDialog.OpenFile()) != null)
                    {
                        using (stream)
                        {
                            Editcap editcap = new Editcap();
                            if (!editcap.isLibpcapFormat(file))
                            {
                                string fileToAdd = editcap.getNewFileName(file);
                                backgroundWorker.ReportProgress(0, fileToAdd);
                            }
                            else
                            {
                                backgroundWorker.ReportProgress(0, file);
                            }


                            lastPath = Path.GetDirectoryName(thisDialog.FileNames[0]);
                        }
                    }
                }

                catch (Exception ex)
                {
                    MessageBox.Show("Error: Could not read file from disk. Original error: " + ex.Message);
                }
            }
        };

        backgroundWorker.ProgressChanged +=
            (s3, arguments) =>
            {
                listBoxFiles.Items.Add(arguments.UserState);
            };

        backgroundWorker.RunWorkerAsync();

    }
}
票数 2
EN

Stack Overflow用户

发布于 2012-12-13 04:27:47

您可以使用backgroundWorker完成此操作:通过工具箱将backgroundWorker添加到窗体。

从以下内容开始:

代码语言:javascript
复制
backgroundWorker.RunWorkerAsync(new string[] {parm1, parm2});

将事件添加到backgroundWorker (属性窗口)

使用DoWork进行计算。然后使用RunWorkerCompleted应用设置。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/13847848

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档