Answered by:
GUI update problem

Question
-
Hi,
I'm new to C# and I need some help on how to update the GUI in my application.
I have a list of files that I process and then delete. I want the file list (in the GUI) to be updated as the files are processed, but the GUI is not updated until all the files are processed (when the function doing the file processing has finished)
How do I update the GUI while the file processing function is running?
Any suggestions are appreciated.- Moved by Peter Ritchie Friday, June 20, 2008 4:49 PM off-topic
Monday, June 16, 2008 12:57 PM
Answers
-
Hello,
If you are using "BackgroundWorker" class, move the code which is in "start_click" to "Backgroundworkers" "DoWork" event handler. Inside "ProgressChanged" event handler, update the progress bar. Say you have a "BackgroundWorker" instance named "worker".worker = new BackgroundWorker(); // Hooking events worker.DoWork += new DoWorkEventHandler(worker_DoWork); worker.ProgressChanged += new ProgressChangedEventHandler(worker_ProgressChanged); //Fired when progress changes worker.RunWorkerCompleted += new RunWorkerCompletedEventHandler(worker_RunWorkerCompleted); // Fired when worker completes or cancels // Setting worker bahaviour worker.WorkerReportsProgress = true; worker.WorkerSupportsCancellation = true; // Doing the work worker.RunWorkerAsync(); // Start the work on DoWork event handler
Write the above code inside start_click. Inside "worker_DoWork" method, write your code for processing. To update progress, call "worker.ReportProgress()". Inside "worker_progresschanged" event handler, write code to update the progress bar.
Hope this will help
Sincerly, Navaneeth.K.N- Marked as answer by jack 321 Friday, June 20, 2008 10:31 AM
Thursday, June 19, 2008 12:32 PM
All replies
-
You might want to study how threading works is C#. You will have to create a separate thread for your application that will process the files and update the GUI. As Microsoft states on their documentation,
The advantage of threading is the ability to create applications that use more than one thread of execution. For example, a process can have a user interface thread that manages interactions with the user and worker threads that perform other tasks while the user interface thread waits for user input.
Click here for full
Microsoft Documentation
Hope this helps,
-Tudor
19 years old student http://www.tudoralex.com- Proposed as answer by Tudor Alexandru Monday, June 16, 2008 1:01 PM
Monday, June 16, 2008 1:01 PM -
This is happening because you are running everything in the main thread. You need to run the deletion process in a separate thread to keep your GUI active. Use "BackgroundWorker" class to do this easily. It provides internal mechanism to handle GUI updates and progress reporting. I have an article on this. Please read Threading with BackgroundWorker
Hope this helps
Sincerly, Navaneeth.K.N- Proposed as answer by Navaneeth Thursday, June 19, 2008 8:35 AM
Monday, June 16, 2008 1:24 PM -
Hi,
thanks for the help.
I've tried both the background worker and delegate that i found in the documentation, but the gui is not updated until the loop doing the file processing has finished, so I still have the same problem :(
I found a producer consumer threading example that I tried, but when I try do update the gui delegate does not work.
Maybe I'm doing this the wrong way, please help.Thursday, June 19, 2008 5:24 AM -
Please post the code you used.
Sincerly, Navaneeth.K.NThursday, June 19, 2008 7:20 AM -
Hi KingVoodoo,
Maybe you can try to take a look at how to update a Windows Form control in a separate Worker thread, The LINK below.
How to: Make Thread-Safe Calls to Windows Forms Controls
Based on my experience, the BackgroundWorker class is a nice choice for this situation, if you still cannot figure the issue out, please post the detailed code here and let us know what the problem is.
Regards,
Xun
Please remember to mark the replies as answers if they help and unmark them if they provide no help.- Edited by jack 321 Thursday, June 19, 2008 7:35 AM add a word
Thursday, June 19, 2008 7:33 AM -
Hi,
thanks again.
Here is the code i'm using (I hope that's all you need)
private void UpdateGUI() { while (true) { if (bInTransfer && !bComplete) { // Update status SetStatus("In Transfer"); bInTransfer = false; } if (bComplete && !bInTransfer) { // Update status SetStatus("Transfer Complete"); bComplete = false; } } } public Form1() { ... // start gui update thread try { guiUpdateThread = new Thread(new ThreadStart(UpdateGUI)); guiUpdateThread.Start(); } catch (Exception e) { guiUpdateThread.Abort(); } } private void Start_Click(object sender, EventArgs e) { //Check input fields if ((tbDir.Text != "") && (tbIP.Text != "") && (tbDelay.Text != "") && (tbPort.Text != "")) { // Start Working if (IsDataValid()) { //--------------------------------------------------------------------- if (intNrOfFiles == 0) { //Initialize intMtu = Convert.ToInt32(tbMtu.Text); aData = new byte[intMtu]; //Search dir for files aFiles = Directory.GetFiles(tbDir.Text, "*.*"); // Get number of files in dir. intNrOfFiles = aFiles.Length; //Add files to list view foreach (String strFile in aFiles) { ListViewItem lviEntry = new ListViewItem(strFile); lviEntry.SubItems.Add("Pending"); listFile.Items.Add(lviEntry); } //Process files in list for (int i = 0; i < intNrOfFiles; i++) { intFileIndex = i; bInTransfer = true; strFileToSend = listFile.Items[intFileIndex].Text; try { fi = new FileInfo(strFileToSend); } catch (System.IO.FileNotFoundException ex) { MessageBox.Show(ex.Message); } //Get file size lFileSize = fi.Length; //Get file name strFileName = fi.Name; //Get nr of packets to send intNrOfPackets = (int)lFileSize / intMtu; //Set progressbar values int intSteps = intNrOfPackets + 1; if (intSteps >= 100) { progressBar1.Step = 1; progressBar1.Maximum = intSteps; } else { progressBar1.Step = 100 / intSteps; progressBar1.Maximum = progressBar1.Step * intSteps; } //Create stream reader to read file fs = new FileStream(strFileToSend, FileMode.Open, FileAccess.Read, FileShare.Read); fsTarget = new FileStream("C:\\Temp\\Target\\" + strFileName, FileMode.CreateNew); //Read file for (int j = 0; j < intNrOfPackets; j++) { // fs.Read(aData, 0, intMtu); //Write to new file fsTarget.Write(aData, 0, intMtu); //increase progressbar progressBar1.PerformStep(); } // Read the last bit of the file. aFinalData = new byte[(int)lFileSize % intMtu]; fs.Read(aFinalData, 0, (int)lFileSize % intMtu); fs.Close(); fsTarget.Write(aFinalData, 0, (int)lFileSize % intMtu); fsTarget.Flush(); fsTarget.Close(); //Increment progressbar progressBar1.PerformStep(); //Update Status bInTransfer = false; bComplete = true; //Reset progress bar progressBar1.Value = 0; } ... } //--------------------------------------------------------------------*/ }// End IsDataValid() } else { ... } private void SetStatus(String _text) { if (listFile.InvokeRequired) { SetTextCallback d = new SetTextCallback(SetStatus); this.Invoke(d, new object[] { _text}); } else { this.listFile.Items[intFileIndex].SubItems[intFileIndex].Text = _text; } }
I want the gui to be updated while Start_Click is running.
Right now the list of files is not displayed until Start_Click has ended.
I know there are some synchronization issues, but if I can't see the list thats not a problem.
Thanks in advance.Thursday, June 19, 2008 11:51 AM -
Hello,
If you are using "BackgroundWorker" class, move the code which is in "start_click" to "Backgroundworkers" "DoWork" event handler. Inside "ProgressChanged" event handler, update the progress bar. Say you have a "BackgroundWorker" instance named "worker".worker = new BackgroundWorker(); // Hooking events worker.DoWork += new DoWorkEventHandler(worker_DoWork); worker.ProgressChanged += new ProgressChangedEventHandler(worker_ProgressChanged); //Fired when progress changes worker.RunWorkerCompleted += new RunWorkerCompletedEventHandler(worker_RunWorkerCompleted); // Fired when worker completes or cancels // Setting worker bahaviour worker.WorkerReportsProgress = true; worker.WorkerSupportsCancellation = true; // Doing the work worker.RunWorkerAsync(); // Start the work on DoWork event handler
Write the above code inside start_click. Inside "worker_DoWork" method, write your code for processing. To update progress, call "worker.ReportProgress()". Inside "worker_progresschanged" event handler, write code to update the progress bar.
Hope this will help
Sincerly, Navaneeth.K.N- Marked as answer by jack 321 Friday, June 20, 2008 10:31 AM
Thursday, June 19, 2008 12:32 PM -
For questions and discussions regarding client application development using Windows Forms controls and features, please see http://forums.microsoft.com/msdn/ShowForum.aspx?ForumID=8&SiteID=1
http://www.peterRitchie.com/blog- Marked as answer by Peter Ritchie Friday, June 20, 2008 4:49 PM
- Unmarked as answer by KingVoodoo Thursday, October 16, 2008 8:01 AM
Friday, June 20, 2008 4:48 PM