首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> 更多程式語言 >> 程式設計綜合問答

C# 窗體關閉後線程仍在運行的解決方案

     編輯:程式設計綜合問答

問題現象

在 WinForms 應用中,主窗體關閉並調用 Environment.Exit(0) 或 Process.Kill() 後,進程雖已退出,但後台線程(如打印線程)似乎仍在運行,導致資源未釋放或殘留進程。

原因分析

  • 設置 Thread.IsBackground = true 只會使線程在所有前台線程結束時自動終止,但若主線程強制殺掉進程,後台線程可能來不及執行清理代碼(如 finally 塊)。
  • Environment.Exit 和 Process.Kill 會立即終止進程,不會觸發正常的線程結束流程。

正確處理姿勢

  1. 優雅關閉:在窗體 FormClosing 事件中設置取消標誌,通知後台線程退出循環,然後 Join() 等待其結束。
    private volatile bool _stopPrint = false;
    private Thread _printThread;
    
    private void Form1_FormClosing(object sender, FormClosingEventArgs e) {
        _stopPrint = true;
        if (_printThread != null && _printThread.IsAlive) {
            _printThread.Join(2000); // 最多等待 2 秒
        }
    }
    
    private void PrintLoop() {
        while (!_stopPrint) {
            // 打印邏輯
            Thread.Sleep(100);
        }
        // 清理資源
    }
    
  2. 使用 CancellationToken(.NET 4.0+):更規範的取消模式。
    var cts = new CancellationTokenSource();
    Task.Run(() => {
        while (!cts.Token.IsCancellationRequested) { /* ... */ }
    }, cts.Token);
    // 關閉時
    cts.Cancel();
    
  3. 避免強制殺進程:除非極端情況,否則不應在正常退出流程中使用 Process.Kill()。

參考資源

詳細示例可參考:C# 線程優雅退出最佳實踐

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved