0

首先,我对编程比较陌生。我为我的新工作接受了一些 C# 入门培训,这是我使用的第一门语言。

我最近遇到了一个业务问题,我决定使用 C# 来解决,既是为了节省时间(我曾希望),也是为了在此过程中学习更多 C#。我提到的业务问题是:我需要审核 600 多个 Word 文件。对于每个文件,我必须确保...

  1. 文档中的任何地方都没有带有删除线的文本。
  2. 跟踪更改已禁用。
  3. 没有待处理的更改(如在启用 Track Changes 时所做的更改尚未被接受或拒绝)。
  4. 没有评论。

让我的程序遍历所有文档并在执行过程中进行更改是最快的。但是由于这项任务的性质,我想手动进行更改,将程序的使用限制为生成需要更改的文件列表(共 600 个),并详细说明每个文件需要进行哪些更改.

所以,我有一个调用 FolderBrowserDialog 的按钮。

    private void AddFolderButtonClick(object sender, EventArgs e)
    {
        var folderBrowser = new FolderBrowserDialog();
        if (folderBrowser.ShowDialog() != DialogResult.OK)
        {
            return;
        }
        this.progressBar1.Visible = true;
        this.progressBar1.Style = ProgressBarStyle.Marquee;
        this.Cursor = Cursors.WaitCursor;

        var args = new List<string>(Directory.EnumerateDirectories(folderBrowser.SelectedPath));

        // Get list of files in selected directory, adding to list of directories
        args.AddRange(Directory.EnumerateFiles(folderBrowser.SelectedPath));

        this.displayListBox.BeginUpdate();
        foreach (string path in args)
        {
            if (File.Exists(path))
            {
                // This path is a file
                this.ProcessFile(Path.GetFullPath(path));
            }
            else if (Directory.Exists(path))
            {
                // This path is a directory
                this.ProcessDirectory((Path.GetFullPath(path)));
            }
            else
            {
                Console.WriteLine(Resources.Finder_Invalid_File_Or_Directory, path);
            }
        }

        this.displayListBox.EndUpdate();
        this.progressBar1.Visible = false;
        this.progressBar1.Style = ProgressBarStyle.Continuous;
        this.Cursor = Cursors.Default;
    } 

以下两种方法一起遍历所有子目录和文件,以创建通过 FolderBrowserDialog 选择的顶级目录下所有文件的完整列表:

    private void ProcessDirectory(string targetDirectory)
    {
        // Process the list of files found in the directory. 
        string[] fileEntries = Directory.GetFiles(targetDirectory);
        foreach (string fileName in fileEntries)
        {
            this.ProcessFile(fileName);
        }

        // Recurse into subdirectories of this directory. 
        string[] subdirectoryEntries = Directory.GetDirectories(targetDirectory);
        foreach (string subdirectory in subdirectoryEntries)
        {
            this.ProcessDirectory(subdirectory);
        }
    } 

    private void ProcessFile(string path)
    {
        Console.WriteLine(Resources.Finder_File_Processed, path);
        string fileName = Path.GetFileName(path);
        if (fileName == null || fileName.StartsWith(@"~$") || this.selectedFilesList.Contains(path))
        {
            return;
        }
        this.selectedFilesList.Add(path);
        this.filePathsCountLabel.Text = (@"Count: " + this.selectedFilesList.Count);
        this.displayListBox.Items.Add(path);
    } 

一旦所有这些代码运行,我就会得到一个完整的文档列表。我单击一个按钮,程序从这里开始做它应该做的事情。好的,酷。我之前提到我选择使用 C# 来解决这个问题的一半原因是为了学习。在这一点上,我已经拥有了我需要的一切,但我真正想知道的是如何在生成文件列表时实现线程以使 GUI 响应?我浏览了几个例子。他们说得通。出于某种原因,我只是无法理解这个应用程序。如何在不锁定 GUI 的情况下完成处理子目录和文件的整个过程?

4

2 回答 2

1

我相信你需要的东西都可以在这里找到。简而言之,要使用在单独的线程上完成所有工作从而防止 GUI 冻结的 backgroundworker,首先您要实例化 BackgroundWorker 并处理 DoWork 事件。然后调用 RunWorkerAsync,可选择使用对象参数。

作为骨架代码:

class myClass
{
static BackgroundWorker myBw = new BackgroundWorker();

static void Main()
{
myBw .DoWork += myBw_DoWork;
myBw .RunWorkerAsync ("an argument here");
Console.ReadLine();
}

static void myBw_DoWork (object sender, DoWorkEventArgs e)
{
// This is called on the separate thread, argument is called as e.Argument
// Perform heavy task...
}
}
于 2013-10-02T20:41:44.200 回答
0

您必须创建一个单独的线程来处理您的工作。如果您使用的是 .NET 4.0+ 或旧版本,查看此内容。

使用任务,您可以编写

Task.Factory.StartNew(() => DoAction()

其中 DoAction 是您开始处理数据的函数。

但不要忘记使用 Invoke,如果您想从单独的线程使用 GUI 进行操作。例如,如果你想从单独的线程更新一些标签文本,你必须这样做

label1.Invoke(() => label1.Text = "Some Text");
于 2013-10-02T20:48:47.370 回答