S
Steve B.
Hi,
I'm building an application that performs some long operations against
files.
In order to view the progress, I'm using two background workers.
The first backgroundworker is listing recursively all files in a folder and
each files are queued into a Queue<FileInfo> object.
I'm not using the Directory.GetFiles("*.*", SearchOptions.AllDirectories)
because lisiting all files is quite long and I want to start my process as
soon as on file is found.
The second backgroundworker will execute the process agains each found
files.
I'm wondering how can I properly code my application in order to run the
second background worker only when files are filled. Note that I must run
the background worker from the window thread because the progressedchanged
must change controls properties.
Since the two background worker are started simultaneously, I need a way to
block the second BGWorker until the first file has been found. I using a
while clause but I'm not sure this is a good practice regarding the
performances.
I'm using by now this code snippet :
public partial class Form1 : Form
{
/// <summary>
/// Initializes a new instance of the <see cref="T:Form1"/> class.
/// </summary>
public Form1()
{
InitializeComponent();
m_filesToAnalyse = new Queue<FileInfo>();
m_filesToCompare = new Queue<FileScanResult>();
}
private Queue<FileInfo> m_filesToAnalyse;
private bool m_remainingFiles;
private void button1_Click(object sender, EventArgs e)
{
m_remainingFiles = true;
folderBrowsing.RunWorkerAsync(@"I:\Formations");
filesAnalysing.RunWorkerAsync();
}
private void AnalyseFolder(DirectoryInfo dir) // Used for recursive browsing
{
//Thread.Sleep(50);
folderBrowsing.ReportProgress(0, dir);
Debug.WriteLine("* " + dir.FullName);
foreach (FileInfo file in dir.GetFiles())
{
m_filesToAnalyse.Enqueue(file);
}
foreach (DirectoryInfo subDir in dir.GetDirectories())
{
AnalyseFolder(subDir);
}
}
#region folderBrowsing
private void folderBrowsing_DoWork(object sender, DoWorkEventArgs e)
{
string folder = e.Argument.ToString();
DirectoryInfo dir = new DirectoryInfo(folder);
AnalyseFolder(dir);
}
private void folderBrowsing_ProgressChanged(object sender,
ProgressChangedEventArgs e)
{
listBox1.Items.Insert(0, string.Format(
"Folder : {0}",
((DirectoryInfo)e.UserState).FullName
));
}
private void folderBrowsing_RunWorkerCompleted(object sender,
RunWorkerCompletedEventArgs e)
{
m_remainingFiles = false;
listBox1.Items.Insert(0, "parcours fichiers fini");
}
#endregion
#region filesAnalysing
private void filesAnalysing_DoWork(object sender, DoWorkEventArgs e)
{
lock (m_filesToAnalyse)
{
while (m_remainingFiles || m_filesToAnalyse.Count > 0)
{
if(m_filesToAnalyse.Count > 0)
{
FileInfo fi = m_filesToAnalyse.Dequeue();
filesAnalysing.ReportProgress(0, fi);
Debug.WriteLine("- " + fi.FullName);
/*
* Perform here the custom process
*/
);
}
}
}
}
private void filesAnalysing_ProgressChanged(object sender,
ProgressChangedEventArgs e)
{
listBox1.Items.Insert(0, string.Format(
"Fichier : {0}",
((FileInfo)e.UserState).FullName
));
}
private void filesAnalysing_RunWorkerCompleted(object sender,
RunWorkerCompletedEventArgs e)
{
listBox1.Items.Insert(0, "analyse fichiers fini");
}
#endregion
}
Am I on the right way ?
Thanks in advance,
Steve
I'm building an application that performs some long operations against
files.
In order to view the progress, I'm using two background workers.
The first backgroundworker is listing recursively all files in a folder and
each files are queued into a Queue<FileInfo> object.
I'm not using the Directory.GetFiles("*.*", SearchOptions.AllDirectories)
because lisiting all files is quite long and I want to start my process as
soon as on file is found.
The second backgroundworker will execute the process agains each found
files.
I'm wondering how can I properly code my application in order to run the
second background worker only when files are filled. Note that I must run
the background worker from the window thread because the progressedchanged
must change controls properties.
Since the two background worker are started simultaneously, I need a way to
block the second BGWorker until the first file has been found. I using a
while clause but I'm not sure this is a good practice regarding the
performances.
I'm using by now this code snippet :
public partial class Form1 : Form
{
/// <summary>
/// Initializes a new instance of the <see cref="T:Form1"/> class.
/// </summary>
public Form1()
{
InitializeComponent();
m_filesToAnalyse = new Queue<FileInfo>();
m_filesToCompare = new Queue<FileScanResult>();
}
private Queue<FileInfo> m_filesToAnalyse;
private bool m_remainingFiles;
private void button1_Click(object sender, EventArgs e)
{
m_remainingFiles = true;
folderBrowsing.RunWorkerAsync(@"I:\Formations");
filesAnalysing.RunWorkerAsync();
}
private void AnalyseFolder(DirectoryInfo dir) // Used for recursive browsing
{
//Thread.Sleep(50);
folderBrowsing.ReportProgress(0, dir);
Debug.WriteLine("* " + dir.FullName);
foreach (FileInfo file in dir.GetFiles())
{
m_filesToAnalyse.Enqueue(file);
}
foreach (DirectoryInfo subDir in dir.GetDirectories())
{
AnalyseFolder(subDir);
}
}
#region folderBrowsing
private void folderBrowsing_DoWork(object sender, DoWorkEventArgs e)
{
string folder = e.Argument.ToString();
DirectoryInfo dir = new DirectoryInfo(folder);
AnalyseFolder(dir);
}
private void folderBrowsing_ProgressChanged(object sender,
ProgressChangedEventArgs e)
{
listBox1.Items.Insert(0, string.Format(
"Folder : {0}",
((DirectoryInfo)e.UserState).FullName
));
}
private void folderBrowsing_RunWorkerCompleted(object sender,
RunWorkerCompletedEventArgs e)
{
m_remainingFiles = false;
listBox1.Items.Insert(0, "parcours fichiers fini");
}
#endregion
#region filesAnalysing
private void filesAnalysing_DoWork(object sender, DoWorkEventArgs e)
{
lock (m_filesToAnalyse)
{
while (m_remainingFiles || m_filesToAnalyse.Count > 0)
{
if(m_filesToAnalyse.Count > 0)
{
FileInfo fi = m_filesToAnalyse.Dequeue();
filesAnalysing.ReportProgress(0, fi);
Debug.WriteLine("- " + fi.FullName);
/*
* Perform here the custom process
*/
);
}
}
}
}
private void filesAnalysing_ProgressChanged(object sender,
ProgressChangedEventArgs e)
{
listBox1.Items.Insert(0, string.Format(
"Fichier : {0}",
((FileInfo)e.UserState).FullName
));
}
private void filesAnalysing_RunWorkerCompleted(object sender,
RunWorkerCompletedEventArgs e)
{
listBox1.Items.Insert(0, "analyse fichiers fini");
}
#endregion
}
Am I on the right way ?
Thanks in advance,
Steve