我有一个C#应用程序,它读取文件夹中的所有文件,并将它们存储到一个数组中。然后应用程序将数组写入文本文件。
我想在标签中显示文件的名称。这是我尝试过的,但我的应用程序冻结,它只显示最后一个文件的名称。
private void button1_Click(object sender, EventArgs e)
{
ListAllFiles(@"C:\mmc2", ref label1);
}
private void ListAllFiles(string path, ref Label lbl)
{
string savePath = @"C:\Users\Diza\Desktop\AllFiles.txt";
string[] files = Directory.GetFiles(path,"*.*", SearchOption.AllDirectories);
StreamWriter myWriter = new StreamWriter(savePath);
int count=0;
DateTime dtStart = DateTime.Now;
myWriter.WriteLine("Start: " + dtStart.ToShortTimeString());
foreach (string val in files)
{
lbl.Text = val;
myWriter.WriteLine(val);
count++;
}
}
答案 0 :(得分:4)
您的应用程序正在冻结,因为您正在UI线程中完成所有工作。有许多替代品,比如使用线程,任务,后台工作者等等。
我将向您展示使用任务并行库的实现(假设您使用的是wpf):
private void button1_Click(object sender, EventArgs e)
{
//Start the listing in a task
Task.Factory.StartNew(()=>ListAllFiles(@"C:\mmc2", ref label1));
}
private void ListAllFiles(string path, ref Label lbl)
{
string savePath = @"C:\Users\Diza\Desktop\AllFiles.txt";
string[] files = Directory.GetFiles(path,"*.*", SearchOption.AllDirectories);
StreamWriter myWriter = new StreamWriter(savePath);
int count=0;
DateTime dtStart = DateTime.Now;
myWriter.WriteLine("Start: " + dtStart.ToShortTimeString());
foreach (string val in files)
{
//update the label using the dispatcher (because ui elements cannot be accessed from an non-ui thread
Application.Current.Dispatcher.BeginInvoke(
new Action(()=>lbl.Text = val));
myWriter.WriteLine(val);
count++;
}
}
如果您使用.net 4.5,则另一种方法是使用StreamWriter的WriteLineAsync:
myWriter.WriteLineAsync(val);
答案 1 :(得分:2)
永远不要在UI线程中执行IO。
使用Stream
上可用的*异步方法,或者旋转任务以异步写入文件。
答案 2 :(得分:0)
这是BackgroundWorker
中理想的事情。它允许您通过ProgressChanged
事件或Control.Invoke
/ Dispatcher.Invoke
更新UI线程中的显示。
答案 3 :(得分:0)
BackgroundWorker类允许您在单独的专用线程上运行操作。下载和数据库事务等耗时的操作可能会导致用户界面(UI)在运行时停止响应。当您需要响应式UI并且您遇到与此类操作相关的长时间延迟时,BackgroundWorker类提供了一种方便的解决方案。
结帐Background Worker。 它包括代码示例。