如何实时更新后台工人工作事件中的目录信息数组变量



我有一个带有两个后台工作人员的按钮单击事件。

static DirectoryInfo[] MySubDirectories;
        private void btnProcess_Click(object sender, EventArgs e)
        {
            btnProcess.Enabled = false;
            btnDirectory.Enabled = false;
            btnCancel.Visible = true;
            btnCancel.Enabled = true;
            btnCancel.Text = "Cancel";
            MyProgressBar.Visible = true;
            _FileProcessingWorker = new BackgroundWorker();
            _FileProcessingWorker.WorkerReportsProgress = true;
            _FileProcessingWorker.WorkerSupportsCancellation = true;
            _FileProcessingWorker.DoWork += new DoWorkEventHandler(_FileProcessingWorker_DoWork);
            _FileProcessingWorker.ProgressChanged += new ProgressChangedEventHandler(_FileProcessingWorker_ProgressChanged);
            _FileProcessingWorker.RunWorkerCompleted += new RunWorkerCompletedEventHandler(_FileProcessingWorker_RunWorkerCompleted);
            _FileInformationWorker = new BackgroundWorker();
            _FileInformationWorker.WorkerReportsProgress = true;
            _FileInformationWorker.WorkerSupportsCancellation = true;
            _FileInformationWorker.DoWork += new DoWorkEventHandler(_FileInformationWorker_DoWork);
            _FileInformationWorker.ProgressChanged += new ProgressChangedEventHandler(_FileInformationWorker_ProgressChanged);
            _FileInformationWorker.RunWorkerCompleted += new RunWorkerCompletedEventHandler(_FileInformationWorker_RunWorkerCompleted);
            if (BasePath != null)
            {
                _FileInformationWorker.RunWorkerAsync();
            }
        }

在第一个后台工作者中,我做的dowork事件中的_FileInformationWorker

private void  _FileInformationWorker_DoWork(object sender, DoWorkEventArgs e)
        {
            MySubDirectories = GetDirectories(BasePath).ToArray();
        }

然后是 GetDirectory 方法

private List<DirectoryInfo> GetDirectories(string basePath)
        {
            IEnumerable<string> str = MyGetDirectories(basePath);
            List<DirectoryInfo> l = new List<DirectoryInfo>();
            l.Add(new DirectoryInfo(basePath));
            IEnumerable<DirectoryInfo> dirs = str.Select(a => new DirectoryInfo(a));
            l.AddRange(dirs);
            return l;
        }

和 MyGetDirectory 方法

int countDirectories = 0;
    private IEnumerable<string> MyGetDirectories(string basePath)
    {
        try
        {
            string[] dirs = Directory.GetDirectories(basePath);
            countDirectories = countDirectories + dirs.Length;
            _FileInformationWorker.ReportProgress(countDirectories);
            return dirs.Union(dirs.SelectMany(dir => MyGetDirectories(dir)));
        }
        catch (UnauthorizedAccessException)
        {
            return Enumerable.Empty<string>();
        }
    }

然后在第一个后台工作者进度更改事件中,我正在使用实时计数的目录数更新标签

private void _FileInformationWorker_ProgressChanged(object sender, ProgressChangedEventArgs e)
        {
            label2.Text = e.ProgressPercentage.ToString();
        }

现在,当第一个后台工作者工作时_FileInformationWorker我需要等到方法MyGetDirectory完成他的进程,仅在方法完成后获取所有目录,然后在DoWork事件中变量MySubDirectory不会为空。

但是,与其等待方法MyGetDirectory完成,我希望在DoWork事件中实时更新,或者以某种方式在progresschange事件中,带有目录的变量MySubDirectory已经实时获得。然后,当 MySubDirectory 即使长度为 1 或更多时,启动第二个后台工作线程并在 MySubDirectory 上工作。

并继续在第一个后台工作线程中更新 MySubDirectory,同时在第二个后台工作线程中继续处理它。

这是第二个后台工作人员办公事件:

private void _FileProcessingWorker_DoWork(object sender, DoWorkEventArgs e)
        {
            int countmore = 0;
            try
            {
                DirectoryInfo[] MySubDirectories = (DirectoryInfo[])e.Argument;
                for (int i = 0; i < MySubDirectories.GetLength(0); i++)
                {
                    DirectoryInfo MySubDirectory = MySubDirectories[i];
                    List<FileInfo> l = new List<FileInfo>();
                    CountFiles(MySubDirectory, l);
                    int totalFiles = l.Count;
                    object[] CurrentStatus = new object[5];
                    CurrentStatus[3] = i.ToString();
                    countmore += totalFiles;
                    CurrentStatus[4] = countmore;
                    _FileProcessingWorker.ReportProgress(0, CurrentStatus);
                    string CurrentDirectory = "Current Directory: " + MySubDirectory.Name;
                    foreach (FileInfo MyFile in l)
                    {
                        CurrentStatus = new object[5];
                        if (_FileProcessingWorker.CancellationPending)
                        {
                            e.Cancel = true;
                            return;
                        }
                        if (MyFile.Extension.ToLower() == ".cs" || MyFile.Extension.ToLower() == ".vb")
                        {
                            string CurrentFile = "Current File: " + MyFile.Name;
                            string CurrentFileWithPath = MyFile.FullName;
                            CurrentStatus[0] = CurrentDirectory;
                            CurrentStatus[1] = CurrentFile;
                            _FileProcessingWorker.ReportProgress(0, CurrentStatus);
                            List<string> Result = SearchInFile(CurrentFileWithPath, "ShellContextMenu");
                            if (Result != null && Result.Count > 0)
                            {
                                CurrentStatus[2] = Result;
                                _FileProcessingWorker.ReportProgress(0, CurrentStatus);
                            }
                        }
                    }
                }
            }
            catch (Exception err)
            {
                return;
            }
        }

这就是我应该如何启动第二个后台工作者,但还不确定在哪里做,我曾经在按钮单击事件中这样做,但现在我需要在其他地方做一些事情,也许在第一个后台工作者做工作事件中?

int SubDirectoryCount = MySubDirectories.GetLength(0);
                MyProgressBar.Minimum = 0;
                MyProgressBar.Step = 1;
                MyProgressBar.Maximum = SubDirectoryCount;
                MyProgressBar.Value = MyProgressBar.Minimum;
                _LastCounter = 0;
                _FileProcessingWorker.RunWorkerAsync(MySubDirectories);

主要问题是如何实时更新第一个后台工作者中的变量 MySubDirectory,而不是等到后台工作者完成该过程。

以及如何以及在何处启动第二个后台工作线程,以及如何从最后一个点开始循环第二个后台工作线程中的 MySubDirectory 变量,而不是在目录上重新遍历,而只在最后一个添加的目录上循环。

您是否考虑过使用一些公共布尔变量?也许它可以帮助了解一个程序何时结束并且必须继续另一个程序。

最新更新