简体   繁体   中英

How can i sum a changing values in int variable ? And what is the real number of directories on hard disk?

Backgroundworker dowork event

string CurrentFileWithPath;
        private void _FileProcessingWorker_DoWork(object sender, DoWorkEventArgs e)
        {
            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();
                    CurrentStatus[4] = totalFiles.ToString();
                    _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, "static class FileShellExtension");

                            if (Result != null && Result.Count > 0)
                            {
                                CurrentStatus[2] = Result;
                                _FileProcessingWorker.ReportProgress(0, CurrentStatus);
                            }
                        }
                    }
                }
            }
            catch (Exception err)
            {
                return;
            }

Progresschanged event

private void _FileProcessingWorker_ProgressChanged(object sender, ProgressChangedEventArgs e)
        {
            if (typeof(object[]) == e.UserState.GetType())
            {
                object[] StatusMsg = (object[])e.UserState;
                if (5 == StatusMsg.GetLength(0))
                {
                    label2.Text = StatusMsg[4].ToString();
                    label4.Text = StatusMsg[3].ToString();

                    if (StatusMsg[0] != null && StatusMsg[1] != null)
                    {
                        lblCurrentDirectory.Text = StatusMsg[0].ToString();
                        lblStatus.Text = StatusMsg[1].ToString();
                    }
                    if (StatusMsg[2] != null)
                    {
                        if (StatusMsg[2].GetType() == typeof(List<string>))
                        {
                            List<string> l = (List<string>)StatusMsg[2];

                            for (int i = 0; i < l.Count; i++)
                            {
                                ListViewCostumControl.lvnf.Items.Add("Directory: " + lblCurrentDirectory.Text + "In File: " + lblStatus.Text + l[i]);
                                w.WriteLine("Directory: " + lblCurrentDirectory.Text + "In File: " + lblStatus.Text + l[i]);
                            }
                        }
                    }
                }
            }
        }

CountFiles method

private void CountFiles(DirectoryInfo di, List<FileInfo> l)
        {
            try
            {
                l.AddRange(di.EnumerateFiles());
            }
            catch
            {
                string fff = "";
            }

            try
            {
                IEnumerable<DirectoryInfo> subDirs = di.EnumerateDirectories();
                if (subDirs.Count() > 0)
                {
                    foreach (DirectoryInfo dir in subDirs)
                        CountFiles(dir, l);
                }
            }
            catch 
            {
                string yyy = "";
            }
        }

SearchInFile method

private List<string> SearchInFile(string fileToSearch, string textToSearch)
        {
            List<string> l = new List<string>();
            try
            {
                foreach (var line in File.ReadAllLines(fileToSearch))
                {
                    if (line.Contains(textToSearch))
                        l.Add(line);
                }
            }
            catch(Exception err)
            {
                string fff = err.ToString();
            }

            return l;
        }

The first problem is when getting the number of directories:

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);
            string BasePath = lblDirectoryName.Text;
            DirectoryInfo MyDirectory = new DirectoryInfo(BasePath);
            DirectoryInfo[] MySubDirectories = MyDirectory.GetDirectories();
            int SubDirectoryCount = MySubDirectories.GetLength(0);
            MyProgressBar.Minimum = 0;
            MyProgressBar.Step = 1;
            MyProgressBar.Maximum = SubDirectoryCount;
            MyProgressBar.Value = MyProgressBar.Minimum;
            _LastCounter = 0;
            _FileProcessingWorker.RunWorkerAsync(MySubDirectories);
        }

In the click button i'm getting the sub directories. But there are two problems. In the dowork event when i put a break point on this line:

for (int i = 0; i < MySubDirectories.GetLength(0); i++)

I see that it contain 409 directories. But when i report the number of directories to the label4 in the dowork event

CurrentStatus[3] = i.ToString();

In the progresschanged event

 label4.Text = StatusMsg[3].ToString();

I see in the end on label4 408 directories. And in D:(in this case i'm working on my D:\\ directory) when i select all the directories in windows explorer make right click and properties i see only 405 directories. So what is the real number of directories ? What and how number of directories should i display in label4 ?

The second problem is when i report the number of files in dowork event:

CurrentStatus[4] = totalFiles.ToString();

And in progresschanged event show it on label2:

label2.Text = StatusMsg[4].ToString();

The problem is that the totalFiles value is changing all the time once it's 2 then it's 768 then it's 66 then 8987 but what i want to do is somehow to sum in real time the values in totalFiles so in label2 i will see first time for example: 2 then 770 then (770+66) so i will see in label2 816....to see always the sum of all the values so far.

The last problem is in the progresschanged event this loop:

for (int i = 0; i < l.Count; i++)
                                {                                    ListViewCostumControl.lvnf.Items.Add("Directory: " + lblCurrentDirectory.Text + "In File: " + lblStatus.Text + l[i]);
                                    w.WriteLine("Directory: " + lblCurrentDirectory.Text + "In File: " + lblStatus.Text + l[i]);
                                }

It might be logic somehow to take out and make this loop at this time in the program in another backgroundworker like backgroundworker2 dowork event ? If so how to do it ? The problem is when the loop have many items to add to the listView it make the program to hang until the loop finish.

Each time you execute

CurrentStatus[4] = totalFiles.ToString();

You are resetting the status value to the count of files in the current processing directory. This is why the number keeps bouncing around. Instead I would suggest:

int thisDirFiles;
thisDirFiles = l.Count;
totalFiles += thisDirFiles;
CurrentStatus[4] = totalFiles.ToString();

Now when you report progress, CurrentStatus[4] will have the running total.

For your second question, it looks to me you are trying to do too much when you are reporting progress. Manipulating ListViews can be costly, and you are probably spending more time updating the ListView than you are processing the directories, so your machine seems to freeze.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM