首页 > 后端开发 > C++ > 如何从不同类中的单独线程安全地更新 WPF UI?

如何从不同类中的单独线程安全地更新 WPF UI?

Susan Sarandon
发布: 2025-01-05 18:25:41
原创
841 人浏览过

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
作者最新文章
热门教程
更多>
最新下载
更多>
网站特效
网站源码
网站素材
前端模板