C# 如何向backgroundworker progresschanged事件实时报告目录数?

C# 如何向backgroundworker progresschanged事件实时报告目录数?,c#,.net,winforms,C#,.net,Winforms,在这两个方法GetDirectories和MyGetDirectories中,我得到递归的所有目录和子目录。我想在progresschanged事件中的label2上显示一个计数器,它可以计算目录的数量,直到完成为止 private void _FileInformationWorker_DoWork(object sender, DoWorkEventArgs e) { MySubDirectories = GetDirectories(BasePat

在这两个方法GetDirectories和MyGetDirectories中,我得到递归的所有目录和子目录。我想在progresschanged事件中的label2上显示一个计数器,它可以计算目录的数量,直到完成为止

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

        private void _FileInformationWorker_ProgressChanged(object sender, ProgressChangedEventArgs e)
        {

        }
然后是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;
        }
在这件事上

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

但是它并没有向label2报告任何我想的事情,因为它仍然在GetDirectories方法中工作。所以我被困在这里。

确保您已将以下设置为真:

_FileInformationWorker.WorkerReportsProgress = true;
还应确保按照以下方式异步启动工作:

_FileInformationWorker.RunWorkerAsync();

示例也可以帮助您完成任务。

这是一个表单代码,上面只有按钮和标签:

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.IO;

namespace WindowsFormsApplication1
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }

        DirectoryInfo[] MySubDirs;
        BackgroundWorker w;
        int count;

        private void button1_Click(object sender, EventArgs e)
        {
            button1.Enabled = false;
            count = 0;
            w = new BackgroundWorker();
            w.DoWork += w_DoWork;
            w.ProgressChanged += w_ProgressChanged;
            w.WorkerReportsProgress = true;
            w.RunWorkerCompleted += w_RunWorkerCompleted;
            w.RunWorkerAsync();

        }

        void w_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
        {
            button1.Enabled = true;
        }

        void w_ProgressChanged(object sender, ProgressChangedEventArgs e)
        {
            label1.Text = e.UserState.ToString();
        }

        void w_DoWork(object sender, DoWorkEventArgs e)
        {
            MySubDirs = GetDirectories("d:\\prj").ToArray();
        }

        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;
        }
        //not static so we can report progress from it
        private IEnumerable<string> MyGetDirectories(string basePath)
        {
            try
            {
                string[] dirs = Directory.GetDirectories(basePath);
                count += dirs.Length;
                w.ReportProgress(0, count.ToString());
                return dirs.Union(dirs.SelectMany(dir => MyGetDirectories(dir)));
            }
            catch (UnauthorizedAccessException)
            {
                return Enumerable.Empty<string>();
            }
        }
    }
}
使用系统;
使用System.Collections.Generic;
使用系统组件模型;
使用系统数据;
使用系统图;
使用System.Linq;
使用系统文本;
使用System.Windows.Forms;
使用System.IO;
命名空间Windows窗体应用程序1
{
公共部分类Form1:Form
{
公共表格1()
{
初始化组件();
}
DirectoryInfo[]MySubDirs;
背景工人w;
整数计数;
私有无效按钮1\u单击(对象发送者,事件参数e)
{
按钮1.启用=错误;
计数=0;
w=新的后台工作人员();
w、 道工+=w_道工;
w、 ProgressChanged+=w_ProgressChanged;
w、 WorkerReportsProgress=true;
w、 RunWorkerCompleted+=w_RunWorkerCompleted;
w、 RunWorkerAsync();
}
void w_RunWorkerCompleted(对象发送方,RunWorkerCompletedEventArgs e)
{
按钮1.启用=真;
}
void w_ProgressChanged(对象发送方,progresschangedventargs e)
{
label1.Text=e.UserState.ToString();
}
无效w_DoWork(对象发送方,DoWorkEventArgs e)
{
MySubDirs=GetDirectories(“d:\\prj”).ToArray();
}
私有列表GetDirectory(字符串基路径)
{
IEnumerable str=MyGetDirectory(基本路径);
列表l=新列表();
l、 添加(新目录信息(基本路径));
IEnumerable dirs=str.Select(a=>newdirectoryinfo(a));
l、 AddRange(dirs);
返回l;
}
//不是静态的,所以我们可以从中报告进度
私有IEnumerable MyGetDirectory(字符串基路径)
{
尝试
{
字符串[]dirs=Directory.GetDirectories(basePath);
计数+=直接长度;
w、 ReportProgress(0,count.ToString());
返回dirs.Union(dirs.SelectMany(dir=>MyGetDirectories(dir));
}
捕获(未经授权的访问例外)
{
返回可枚举的.Empty();
}
}
}
}

我已经设置好了。解决方案是将ReportProgress行:_FileInformationWorker.ReportProgress移到MyGetDirectories方法中更新计数器的行之后:countDirectories=countDirectories+dirs.Length;现在它开始工作了。shibormot谢谢,我会把它标记为答案。我还有一个问题,但不确定是否要提出一个新问题。目录数量的报告现在正在工作。但是,如果我想实时向变量MySubDirs报告目录,该怎么办?我的意思是,现在在你的代码和我的代码中,我们需要等待获取目录的操作完成,然后MySubDirs不为null,并且在其中包含目录。但是因为我正在使用另一个后台工作人员来处理MySubdir。也许是为了报告并用我已经得到的目录填充MySubdir。我正在做的是在另一个backgroundworker中的MySubDirs目录上循环,并在MySubDirs中的这个目录中搜索。我想知道如何启动第二个backgroundworker并在第一个backgroundworker完成此过程之前处理MySubDirs。最好提出新问题,因为这不是一个简短的回答。我将用我的代码提出一个新问题,因为它现在正在工作。谢谢
_FileInformationWorker.WorkerReportsProgress = true;
_FileInformationWorker.RunWorkerAsync();
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.IO;

namespace WindowsFormsApplication1
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }

        DirectoryInfo[] MySubDirs;
        BackgroundWorker w;
        int count;

        private void button1_Click(object sender, EventArgs e)
        {
            button1.Enabled = false;
            count = 0;
            w = new BackgroundWorker();
            w.DoWork += w_DoWork;
            w.ProgressChanged += w_ProgressChanged;
            w.WorkerReportsProgress = true;
            w.RunWorkerCompleted += w_RunWorkerCompleted;
            w.RunWorkerAsync();

        }

        void w_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
        {
            button1.Enabled = true;
        }

        void w_ProgressChanged(object sender, ProgressChangedEventArgs e)
        {
            label1.Text = e.UserState.ToString();
        }

        void w_DoWork(object sender, DoWorkEventArgs e)
        {
            MySubDirs = GetDirectories("d:\\prj").ToArray();
        }

        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;
        }
        //not static so we can report progress from it
        private IEnumerable<string> MyGetDirectories(string basePath)
        {
            try
            {
                string[] dirs = Directory.GetDirectories(basePath);
                count += dirs.Length;
                w.ReportProgress(0, count.ToString());
                return dirs.Union(dirs.SelectMany(dir => MyGetDirectories(dir)));
            }
            catch (UnauthorizedAccessException)
            {
                return Enumerable.Empty<string>();
            }
        }
    }
}