There was a question of the following plan: I want to put ProgressBar about informing the user that files are being checked ( .xlsx ). It checks for sufficient time ... And here, it means that one problem occurs, when checking the program stops responding and, accordingly, the ProgressBar does not fill up, only after the program hangs, the ProgressBar immediately fills up.

 private void button4_Click_1(object sender, EventArgs e) { string StartupPath = Application.StartupPath; X509Chain chain = new X509Chain(); string[] file = Directory.GetFiles(Properties.Settings.Default.ExtractDir, textBox1.Text, SearchOption.AllDirectories); // ΠΌΠ΅Ρ‚ΠΎΠ΄ поиска Ρ„Π°ΠΉΠ»ΠΎΠ² ".xlsx" ΠΏΠΎ массиву foreach (string ex in file) { string document = Path.Combine(Properties.Settings.Default.ExtractDir, ex); try { using (Package package = Package.Open(document)) // ΠžΡ‚ΠΊΡ€Ρ‹Π²Π°Π΅ΠΌ Π΄ΠΎΠΊΡƒΠΌΠ΅Π½Ρ‚ { listBox1.Items.Add("Π€Π°ΠΉΠ» '" + Path.GetFileName(ex) + "':"); //запись Ρ„Π°ΠΉΠ»Π° PackageDigitalSignatureManager dsm = new PackageDigitalSignatureManager(package); if (!dsm.IsSigned) //ΠΏΡ€ΠΎΠ²Π΅Ρ€ΠΊΠ° Π΄ΠΎΠΊΡƒΠΌΠ΅Π½Ρ‚Ρ‹ Π½Π° Π½Π°Π»ΠΈΡ‡ΠΈΠ΅ подписи { listBox1.Items.Add("Π”ΠΎΠΊΡƒΠΌΠ΅Π½Ρ‚ Π½Π΅ подписан."); } int count = 1; foreach (PackageDigitalSignature pds in dsm.Signatures) { string s = pds.Signer.GetName(); string text = s.Remove(0, s.IndexOf("CN=")); listBox1.Items.Add(count++ + "." + " Подпись Π½Π° сСртификатС :" + text); //подпись Π½Π° сСртификатС if (chain.Build(new X509Certificate2(pds.Signer))) //условиС ΠΏΡ€ΠΎΠ²Π΅Ρ€ΠΊΠΈ Π΄Π΅ΠΉΡΡ‚Π²ΠΈΡ‚Π΅Π»ΡŒΠ½ΠΎΡΡ‚ΠΈ сСртификата listBox1.Items.Add(" сСртификат дСйствитСлСн"); else listBox1.Items.Add(" сСртификат нСдСйствитСлСн"); } } } catch // ΠΎΠ±Ρ€Π°Π±ΠΎΡ‚ΠΊΠ° ΠΈΡΠΊΠ»ΡŽΡ‡Π΅Π½ΠΈΡ { listBox1.Items.Add("Π€Π°ΠΉΠ» '" + Path.GetFileName(ex) + "':"); listBox1.Items.Add("- Π½Π΅Π²Π΅Ρ€Π½Ρ‹ΠΉ Ρ„ΠΎΡ€ΠΌΠ°Ρ‚ "); } } } 

1 answer 1

You did not provide the code that works with ProgressBar, but the symptoms of your problem are clear.

You have processor-intensive code, and you call it on the main thread. But in UI frameworks, unlike command line programs, an event model is adopted: the UI sends events that need to be quickly processed by the program, and in the intervals between such processing it deals with the drawing of the UI itself. In your case, the button click processing takes a very long time, and all this time the UI is not updated in this way! When processing ends, the UI β€œcatches up” with the state in which it should be, since it has time for this.

The traditional solution to such problems here is multithreading. You have to redo the code so that the long operation only starts in another thread (this is fast) and your code does not wait for it to finish. When the operation runs to the end, it can somehow inform the rest of the application that there is a result, you can show it to the user (this is done again in the main stream).

No asynchrony anywhere.


A modern method of implementing asynchrony is to use async / await. Be sure to read about it, with it your problem is solved very simply:

 async Task ProcessWithProgress() { var progress = new Progress<double>(v => YourProgressBar.Value = v); var messages = new Progress<string>(s => listBox1.Items.Add(s + "\n")); await Task.Run(() => ProcessFilesWithProgress(progress, messages)); } void ProcessFilesWithProgress(IProgress<double> progress, IProgress<string> messages) { progress.Report(0); // ... int index = 0; foreach (string ex in file) { index++; string document = Path.Combine(Properties.Settings.Default.ExtractDir, ex); try { using (Package package = Package.Open(document)) { messages.Report("Π€Π°ΠΉΠ» '" + Path.GetFileName(ex) + "':"); PackageDigitalSignatureManager dsm = new PackageDigitalSignatureManager(package); if (!dsm.IsSigned) messages.Report("Π”ΠΎΠΊΡƒΠΌΠ΅Π½Ρ‚ Π½Π΅ подписан."); // ... } } catch { messages.Report("Π€Π°ΠΉΠ» '" + Path.GetFileName(ex) + "': Π½Π΅Π²Π΅Ρ€Π½Ρ‹ΠΉ Ρ„ΠΎΡ€ΠΌΠ°Ρ‚ "); } progress.Report((double)i / file.Length * 100); } }