首頁 >後端開發 >C++ >如何從不同類中的單獨執行緒安全地更新 WPF UI?

如何從不同類中的單獨執行緒安全地更新 WPF UI?

Susan Sarandon
Susan Sarandon原創
2025-01-05 18:25:41803瀏覽

How to Safely Update a WPF UI from a Separate Thread in a Different Class?

從單獨類別中的另一個執行緒更新 UI

您遇到從執行單獨類別的執行緒更新 WPF UI 的常見問題。 UI 在冗長的計算過程中凍結,您需要通知使用者進度。

使用執行緒和事件的解決方案

  1. 調度程式。呼叫: 若要從另一個執行緒更新 UI,請使用 Dispatcher.Invoke。要從單獨的類別中呼叫它,請使用事件。
  2. 事件註冊:在主類別中,註冊由計算類別觸發的事件。
  3. 事件通知: 在計算類別中,當有更新時引發事件以通知UI

範例程式碼:

class MainWindow : Window
{
    private void startCalc()
    {
        // Prepare input
        inputValues input = ...;

        // Create calculation class and register to its event
        CalcClass calc = new CalcClass();
        calc.ProgressUpdate += (s, e) => Dispatcher.Invoke(() => { /* UI Update */ });

        // Start calculation in a separate thread
        Thread calcthread = new Thread(new ParameterizedThreadStart(calc.testMethod));
        calcthread.Start(input);
    }
}

class CalcClass
{
    public event EventHandler ProgressUpdate;

    public void testMethod(object input)
    {
        // Raise event to trigger UI update
        if (ProgressUpdate != null)
            ProgressUpdate(this, new YourEventArgs(status)); // Notify UI with status updates
    }
}

.NET 4.5及更高版本的替代方案

考慮以下使用較新的替代方案功能:

使用任務:用任務取代執行緒以簡化執行緒管理。

使用非同步/等待:延遲計算直到它需要透過將 UI 更新方法標記為非同步來實現。

強烈使用類型化通用事件: 使用強型別通用事件將自訂資料型別傳遞給事件。

有擴充的改進範例:

class MainWindow : Window
{
    Task calcTask = null; // Stores task for later checking

    void StartCalc()
    {
        var calc = PrepareCalc();
        calcTask = Task.Run(() => calc.TestMethod(input)); // Start in background
    }

    async Task CalcAsync()
    {
        var calc = PrepareCalc();
        await Task.Run(() => calc.TestMethod(input)); // Await completion
    }

    CalcClass PrepareCalc()
    {
        // Prepare input and create calc object
        var calc = new CalcClass();
        calc.ProgressUpdate += (s, e) => Dispatcher.Invoke(() => { /* UI Update */ });
        return calc;
    }
}

class CalcClass
{
    public event EventHandler<EventArgs<YourStatus>> ProgressUpdate;

    public TestMethod(InputValues input)
    {
        // Raise event to trigger UI update
        ProgressUpdate?.Raise(this, new EventArgs<YourStatus>(status)); // Raise with status
    }
}

其他注意:

  • 確保高效處理避免競爭條件或潛在死鎖的事件。
  • 考慮從單獨執行緒更新 UI 的效能影響。

以上是如何從不同類中的單獨執行緒安全地更新 WPF UI?的詳細內容。更多資訊請關注PHP中文網其他相關文章!

陳述:
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn