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