Reputation: 21
I have a C# app that reads all the files in a folder, storing them into an array. Then the app writes the array to a text file.
I want to display the name of the file in a label. Here is what I have tried, but my app freezes and it displays only the name of the last file.
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++;
}
}
Upvotes: 2
Views: 6528
Reputation: 1645
The BackgroundWorker class allows you to run an operation on a separate, dedicated thread. Time-consuming operations like downloads and database transactions can cause your user interface (UI) to seem as though it has stopped responding while they are running. When you want a responsive UI and you are faced with long delays associated with such operations, the BackgroundWorker class provides a convenient solution.
Check out Background Worker. It include code examples.
Upvotes: 0
Reputation: 56727
This is the ideal thing to do in a BackgroundWorker
. It allows you to update the display in the UI thread through its ProgressChanged
event or through Control.Invoke
/Dispatcher.Invoke
.
Upvotes: 0
Reputation: 15951
Your application is freezing because you are doing all the work in the UI thread. There are a lot of alternatives like using a thread, a task, a background worker and so on.
I will show you an implementation using the task parallel library (and assuming you are using 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++;
}
}
Another alternative if you are using the .net 4.5 is using the WriteLineAsync of the StreamWriter:
myWriter.WriteLineAsync(val);
Upvotes: 4
Reputation: 7545
Never do IO in the UI thread.
Use *Async methods available on Stream
or spin up a Task to write file asynchronously.
Upvotes: 2