问题
I'm discovering this and can't get to understand how it works.
I have a progress bar in my main form and a menuStrip with a few maintenance functions on a mysql DB. I'd like to monitor progress for each of them.
So I have a class report
and a Progress
progress.
My declarations are as follow :
ProgressReportModel report = new ProgressReportModel();
Progress<ProgressReportModel> progress = new Progress<ProgressReportModel>();
progress.ProgressChanged += ReportProgress;
Now for each of the functions, I usually start with :
report.max = count;
report.visibility = true;
report.PercentageComplete = 0;
showtheProgress(progress);
with ShowtheProgress because I didn't find a way to convert from Progress to IProgress:
private void showtheProgress(IProgress<ProgressReportModel> progress)
{
progress.Report(report);
}
My issue is that this works for some functions but not all.
One difference that i can see if that it works with functions which are async
but not with functions which are not async. To void flooding with code, just gonna put one function which is not working (ie the progressbar is not even showing up):
private void getMp3Files()
{
Globals.counttot = Directory.GetFiles(Globals.pathdir, "*.mp3", SearchOption.AllDirectories).Length;
report.max = Globals.counttot;
report.visibility = true;
report.PercentageComplete = x;
showtheProgress(progress);
DirectoryCopy(Globals.pathdir);
report.visibility = false;
report.PercentageComplete = 0;
showtheProgress(progress);
}
private void DirectoryCopy(string sourceDirName)
{
DirectoryInfo dir = new DirectoryInfo(sourceDirName);
DirectoryInfo[] dirs = dir.GetDirectories();
FileInfo[] files = dir.GetFiles("*.mp3");
foreach (FileInfo file in files)
{
string temppath = Path.Combine(sourceDirName, file.Name);
Mp3 tmp_mp3 = Globals.getTags(temppath);
Globals.AddRowDs(tmp_mp3, false);
report.PercentageComplete = x; //not part of this code but it's a counter
showtheProgress(progress);
}
foreach (DirectoryInfo subdir in dirs) DirectoryCopy(subdir.FullName);
}
Thanks in advance!
回答1:
It's not completely clear from the code that you have posted but my guess is that you have this problem because of the way how winforms works with threads and one of the reasons why the async was 'invented'.
A windows form is based on something like a message queue. Everything that you do on that form like moving your mouse, clicking a button, moving/resizing the form, typing and many more is converted to events and placed in this queue. In the background there is something constantly checking this queue for new events and executing them, one of these events is to draw the screen (paint), basically showing your form on the screen. You can only see the changes that are made (like showing a progress bar) during these paint events. If the time between these paint events is too long you see the message "Not responding".
Some of these events are also clicks on a button and these will execute all the code that you made. If the process of this event takes too long, then you will hold up the message queue and create the "Not responding" message. In order to avoid this, it's suggested to make these events as quick as possible, if you want to execute something that takes a long time, make it on another thread (see BackgroundWorker for an example). One downside of this is that it's not easy to communicate with the form (typically checking InvokeRequired and calling Invoke)
Here is where the async
/await
comes to help you. If you have a button click, and your code encounters an await
that is not done yet, then it will add some code that, once the awaited method is done, it will add an event to the message queue to continue from this point in your code and end the event. This means that the rest of the events in the message queue (like showing that progress bar, displaying some text or handling other button clicks) are possible.
Just to be complete, some can suggest that you can sprinkle your code with Application.DoEvents(), these will force the message queue to be processed while you are still inside the method. This is a quick and dirty way that some people take without knowing the full implications of this. Know that it exists but avoid it.
来源:https://stackoverflow.com/questions/61984119/progress-report-need-help-understanding-how-it-works