MSDN.WhiteKnight - Stack Overflow answers
Ответ на "Ожидание окончания потока при закрытии приложения"
Answer 969736
Проблема в том, что
while (form.trigger_status == "start") { Thread.Sleep(1000); }
блокирует цикл обработки сообщений, так что вызов form.textBox1.Invoke будет вечно ожидать выполнения делегата. Кроме того, проверка свойств в цикле (тем более, строковых) - по меньшей мере, не самый лучший способ синхронизации потоков.
Как сделать это правильно? Логичным решением было бы вместо потоков использовать асинхронные задачи и await. Но можно применить и классический способ с EventWaitHandle и 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); //ожидаем конца фоновой обработки } } } }
Content is retrieved from StackExchange API.
Auto-generated by ruso-archive tools.