-1

I am making a program that reads 1 file and writes it to another file, and the main thing is to make a ProgressBar there that will show progress, but when it starts, it swears that ProgressBar and the charCount variable that reads how many characters in a text file are in another stream. I used Dispatcher.Invoke(() => and the program worked but now it hangs until this thread finishes its job.

Thread thread = new Thread( () => { Dispatcher.Invoke(() => { while (progBar.Value < charCount) { progBar.Value++; Thread.Sleep(100); } }); }); thread.Start(); 

(progBar: ProgressBar name, charCount: stores the number of characters in a text file).

here is a piece of that code. It's strange that the same code without Dispatcher worked in Windows Forms and changed the value of the ProgressBar without hanging. Here it either freezes if you put Sleep(), or instantly changes the value of ProgressBar without Sleep().

I need that while the program is running, the second thread that I create has the ProgressBar value so that the bar fills up without braking the main program.

UPD: I have to use the Thread method.

Here is what the code should look like

Thread thread = new Thread( () => { while (progBar.Value < charCount) { progBar.Value++; Thread.Sleep(100); } }); thread.Start(); 
4
  • What .NET platform are you targeting? .NET 7? Commented Feb 18, 2023 at 12:27
  • 1
    Besides that you should not directly create a Thread, the straightforward solution here is to move Dispatcher.Invoke inside the loop: while (...) { Dispatcher.Invoke(() => progBar.Value++); Thread.Sleep(100); }. And never call Thread.Sleep in the UI thread, e.g. inside a Dispatcher action. Commented Feb 18, 2023 at 12:31
  • And you would of course just use a timer, i.e. a DispatcherTimer in WPF. Commented Feb 18, 2023 at 12:33
  • 1
    With binding it would just work.... Also there is many answersto o similar questions using Progress<T> Commented Feb 18, 2023 at 12:36

1 Answer 1

0

Move the Dispatcher call into the loop body. Otherwise the loop - including the Thread.Sleep call - is executed in the UI thread, which will block all UI updates.

here is a sample code to demonstrate how to read from 1 file and write to another file with a progress presentation. you can change it based on your need

Thread thread = new Thread(() => { using (StreamReader reader = new StreamReader("input.txt")) using (StreamWriter writer = new StreamWriter("output.txt")) { int charCount = (int)reader.BaseStream.Length; int bytesRead = 0; char[] buffer = new char[4096]; int read; while ((read = reader.Read(buffer, 0, buffer.Length)) > 0) { writer.Write(buffer, 0, read); bytesRead += read; if (updateCounter++ % 100 == 0) { int progress = (int)((double)bytesRead / charCount * 100); Dispatcher.BeginInvoke(new Action(() => { progBar.Value = progress; })); } } } }); thread.Start(); 
Sign up to request clarification or add additional context in comments.

2 Comments

This is not a matter of Invoke vs BeginInvoke, but just where the Dispatcher is called. Dispatcher.Invoke never blocks the UI thread.
yes. you are right. we can add if (updateCounter++ % 100 == 0) before Dispatcher call to update progress bar less frequently to avoid blocking. i will update the code

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.