I start a stream in which there is a while loop (true). In the cycle there is

while (form.trigger == "pause") { if (form.trigger_status == "start") { Action action_trigger = () => form.textBox1.Text = "ΠŸΠΎΡ‚ΠΎΠΊ приостановлСн \r\n" + form.textBox1.Text; form.textBox1.Invoke(action_trigger); form.trigger_status = "pause"; } Thread.Sleep(1000); } 

The cycle parses information. It is very important that the parsing is not repeated. In the database, I have already set everything up and marked the control points for starting and stopping parsing. But, when I close the application, of course, the database may not be recorded information, which is very important to me. Therefore, by clicking on the form properties in the form designer, I created a close_app function in the FormClosing events. I wrote the following in it:

 Form1 form = Application.OpenForms["Form1"] as Form1; form.trigger = "pause"; while (form.trigger_status == "start") { Thread.Sleep(1000); } form.myThread.Abort(); form.myThread.Join(); 

But, for some reason in the stream does not reach

 while (form.trigger == "pause") 

Accordingly, the triger_status does not change and the application does not close. What could be the problem?

  • one
    CancellationToken for what? - tym32167 1:14 pm
  • @ tym32167 read. Does not fit - Vladislav Sokolov
  • 2
    read again or explain what exactly does not fit - tym32167

2 answers 2

Instead of these lines:

 while (form.trigger_status == "start") { Thread.Sleep(1000); } form.myThread.Abort(); form.myThread.Join(); 

write the following:

 while (form.myThread.IsAlive) { Application.DoEvents(); } 

this way we wait for the thread to complete without blocking the UI ( Application.DoEvents is responsible for this). In addition, I advise the trigger field to set the volatile - this should be done for all fields that are accessed by multiple threads simultaneously.

In general, I advise you to look towards asynchronous programming using async / await.

    The problem is that

     while (form.trigger_status == "start") { Thread.Sleep(1000); } 

    blocks the message loop, so a call to form.textBox1.Invoke will always wait for the delegate to execute. In addition, checking properties in a loop (especially string ones) is at least not the best way to synchronize threads.

    How to do it right? The logical solution would be to use asynchronous tasks and await instead of threads. But you can apply the classic method with EventWaitHandle and MsgWaitForMultipleObjectsEx:

     using System; using System.Collections.Generic; using System.Text; using System.Windows.Forms; using System.Runtime.InteropServices; using System.Threading; namespace WindowsFormsApp1 { public partial class Form1 : Form { [DllImport("user32.dll")] static extern int MsgWaitForMultipleObjectsEx(uint nCount, IntPtr[] pHandles, uint dwMilliseconds, uint dwWakeMask, uint dwFlags); const uint QS_ALLEVENTS = 1215; const int WAIT_OBJECT_0 = 0; const int WAIT_FAILED = -1; const uint INFINITE = 0xFFFFFFFF; //ΠΎΠΆΠΈΠ΄Π°Π΅Ρ‚ событиС с ΠΎΠ±Ρ€Π°Π±ΠΎΡ‚ΠΊΠΎΠΉ сообщСний public static void WaitEvent(EventWaitHandle evt) { var swh = evt.SafeWaitHandle; using (swh) { IntPtr h = swh.DangerousGetHandle(); while (true) { int res = MsgWaitForMultipleObjectsEx(1, new IntPtr[] { h }, INFINITE, QS_ALLEVENTS, 0); switch (res) { case WAIT_OBJECT_0: return; case WAIT_OBJECT_0 + 1: Application.DoEvents(); break; default: throw new System.ComponentModel.Win32Exception(Marshal.GetLastWin32Error()); } } } } public Form1() { InitializeComponent(); } EventWaitHandle evt; //ΠΎΠ±ΡŠΠ΅ΠΊΡ‚ для синхронизации void DoWork() { evt = new ManualResetEvent(false); try { //выполняСм ΠΎΠΏΠ΅Ρ€Π°Ρ†ΠΈΠΈ... } finally { evt.Set(); //сигнализируСм ΠΎΠ± ΠΎΠΊΠΎΠ½Ρ‡Π°Π½ΠΈΠΈ ΠΎΠ±Ρ€Π°Π±ΠΎΡ‚ΠΊΠΈ } } private void button1_Click(object sender, EventArgs e) { Thread th; th = new Thread(DoWork); th.Start(); //запускаСм ΠΎΠ±Ρ€Π°Π±ΠΎΡ‚ΠΊΡƒ Π² Ρ„ΠΎΠ½ΠΎΠ²ΠΎΠΌ ΠΏΠΎΡ‚ΠΎΠΊΠ΅ } private void Form1_FormClosing(object sender, FormClosingEventArgs e) { if (evt != null) { WaitEvent(evt); //ΠΎΠΆΠΈΠ΄Π°Π΅ΠΌ ΠΊΠΎΠ½Ρ†Π° Ρ„ΠΎΠ½ΠΎΠ²ΠΎΠΉ ΠΎΠ±Ρ€Π°Π±ΠΎΡ‚ΠΊΠΈ } } } }