我必须做一个非常容易的任务:1)列出目录(及其子目录)中的所有文件,2)在多行文本框中显示它们,然后3)在每个文件中做一些东西。我被困在2)由于2个问题,这是我有:BackgroundWorker冻结我的UI和BeginInvoke似乎去乌龟的速度
Form1.cs
就是我管理的UI,并开始一个BackgroundWorker 在运行Logic.cs
的主要功能DependencyMapper.cs
是.. 。好吧,我在那里做文件夹/文件(在Fetch()中),并使用BeginInvoke将每行(当前文件名)填充到Form1的文本框中调用Form1函数。
说话少,代码多。这是我的代码的骨感,不亦乐乎工作版本:
Form1.cs
public partial class Form1 : Form
{
public DependencyMapper dep;
BackgroundWorker bwDep;
public Form1()
{
// I read here in SO to try put the BW stuff here don't know why, but hasn't helped.
InitializeComponent();
bwDep = new BackgroundWorker();
bwDep.DoWork += bwDep_DoWork;
bwDep.RunWorkerCompleted += bwDep_RunWorkerCompleted;
}
private void button1_Click(object sender, EventArgs e)
{
bwDep.RunWorkerAsync();
}
void bwDep_DoWork(object sender, DoWorkEventArgs e)
{
dep.Fetch(extensions);
}
public void SendBack(string msg) // To receive Fetch()s progress
{
textBox2.BeginInvoke(new Action(() =>
{
textBox2.Text += msg + "\r\n";
textBox2.SelectionStart = textBox2.Text.Length;
textBox2.ScrollToCaret();
}));
}
}
DependencyMapper.cs
public class DependencyMapper
{
private Form1 form;
public DependencyMapper(Form1 form1)
{
this.form = form1;
}
public void Fetch()
{
DirectoryInfo folder = new DirectoryInfo(form.Texto1);
FileInfo[] files = folder.GetFiles("*.*", SearchOption.AllDirectories);
for (int i = 0; i < files.Length; i++)
{
form.SendBack(files[i].FullName); // Kind of talking back to the UI through form's reference and SendBack method which uses BeginInvoke.
}
}
}
因此,没有我的应用程序的工作?是的,但两个巨大的问题,我解决不了:
- 它冻结UI(WTF懒BackgroundWorker的?)。不完全是因为文本框逐个添加每个文件,但它像是应该的,但我无法移动窗口或单击任何按钮。
- 这是veeery缓慢。肯定我做错了什么。我的应用程序目前以每秒10个文件的速度填充文本框。而我编码它来查找文本的特定片段在数百个文件... OMG
PS:使用的BackgroundWorker之前,我使用线程:用户界面没有冻结,不过在文本框填充比例为一样慢。这就是为什么我决定冒险与BackgroundWorker,只带来了问题#1。
谢谢。
尝试在窗体初始化之前将线程(背景)准备好与文件夹和文件的列表一起准备好。考虑如何通过表格构建或在全球范围内提供的列表。 – ray
'dep.Fetch(extensions);'什么是dep?什么是扩展?取参数的功能在哪里?请张贴确切的代码。如果适用,考虑只将最终的relult'string []'传递给表单。 –
当您需要在后台执行某些操作时,线程非常方便。自从您不断与用户界面交谈之后,您实际上并未从中受益。当您完全在后台完成繁重的操作并在完成后将结果传递给您的用户界面时,才会带来真正的好处。 – Silvermind