我必須做一個非常容易的任務: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