Hey guys,
I'm trying to read a file and add some nodes to a treee view control. I
would like the GUI to remain interactive and have a progress bar and text box
be updated with info as the file is read.
I'm using a threadpool thread and reading the file from there. However, I
seem to be running into some problems. Sometimes the GUi seems to be
updating/repainting fine but than all of a sudden stops responding. Also, if
the open file dialog is on top off the form, it doesn't repaint at all.
Below is the code I am using. Any help is greatly appreciated.
==============================================
delegate void UpdateProgressBarCallback(decimal percentDone);
delegate void UpdateFlexbarTree(string line);
private void _loadToolStripMenuItem_Click(object sender, EventArgs e)
{
Stream fileStream = null;
OpenFileDialog openFileDialog = new OpenFileDialog();
openFileDialog.InitialDirectory =
Path.GetDirectoryName(Assembly.GetExecutingAssembl y().GetModules()[0].FullyQualifiedName);
openFileDialog.Filter = "lua files (*.lua)|*.lua";
openFileDialog.FilterIndex = 1;
openFileDialog.RestoreDirectory = true;
if (openFileDialog.ShowDialog() == DialogResult.OK)
{
try
{
if ((fileStream = openFileDialog.OpenFile()) != null)
{
ThreadPool.QueueUserWorkItem(new
WaitCallback(CreateFlexbarTree), fileStream);
}
}
catch (Exception ex)
{
MessageBox.Show("Error: Could not read file from disk. Original
error: " + ex.Message);
}
}
}
private void CreateFlexbarTree(object fileStreamState_)
{
Stream fileStream = fileStreamState_ as Stream;
using (fileStream)
{
string line;
decimal fileSize = fileStream.Length;
decimal percentDone = 0;
using (StreamReader streamReader = new StreamReader(fileStream))
{
while ((line = streamReader.ReadLine()) != null)
{
ReadLine(line.Trim());
percentDone = (streamReader.BaseStream.Position / fileSize) * 100;
UpdateProgressBar(percentDone);
}
}
}
}
private void UpdateProgressBar(decimal percentDone_)
{
// InvokeRequired required compares the thread ID of the
// calling thread to the thread ID of the creating thread.
// If these threads are different, it returns true.
if (_readFileProgressBar.InvokeRequired)
{
UpdateProgressBarCallback d = new
UpdateProgressBarCallback(UpdateProgressBar);
Invoke(d, new object[] {percentDone_});
}
else
{
_readFileProgressBar.Value = (int)percentDone_;
//Im not sure but if the textbox is on the same form as the progress
bar, do I need to
//check if Invoke is required for the textbox as well? Either way,
taking out this line didn't seem
//to help
textBox1.Text = percentDone_.ToString();
}
}
private void ReadLine(string line)
{
if (_readFileProgressBar.InvokeRequired)
{
UpdateFlexbarTree d = new UpdateFlexbarTree(ReadLine);
Invoke(d, new object[] {line});
}
else
{
if (line.Contains("FBSavedProfile"))
{
_flexbarDataTree.Nodes.Add("FBSavedProfile");
}
}
}