WPF 根据 UI 线程控制状态更新 NON UI 线程数据

Posted

技术标签:

【中文标题】WPF 根据 UI 线程控制状态更新 NON UI 线程数据【英文标题】:WPF Update NON UI thread data based on UI thread control status 【发布时间】:2014-08-24 17:30:21 【问题描述】:

我创建了一个 wpf 应用程序。其中有一个复选框和两个用于启动和停止计时器的按钮。单击启动按钮 System.Timers.Timer 后,aTimer 将开始运行并调用方法 checkboxstatus() 以获取复选框状态并将其显示给用户。即使选中了复选框,我也会收到消息为 False。我使用了以下代码

public partial class MainWindow : Window
  
    System.Timers.Timer aTimer = new System.Timers.Timer();
    bool ischeckboxchecked = false;

    public MainWindow()
    
        InitializeComponent();
        aTimer.Elapsed += new ElapsedEventHandler(senddata_Tick);
    

    private void button1_Click(object sender, RoutedEventArgs e)
    
        aTimer.Interval = 3000;
        aTimer.Start();
    
    public string checkboxstatus()
    
        string data = string.Empty;
        ischeckboxchecked = false;
        Dispatcher.BeginInvoke((Action)(() =>
        
            if (checkBox1.IsChecked == true)
            
                ischeckboxchecked = true; //value is updating on each timer tick
            
        ));
        data += ischeckboxchecked.ToString();
        return data;
    
    private void senddata_Tick(Object sender, EventArgs args)
    
        string postdata = string.Empty;
        postdata = checkboxstatus(); //every time am getting data as false
        MessageBox.Show(postdata);
    
    private void button2_Click(object sender, RoutedEventArgs e)
    
        aTimer.Stop();
    

    private void checkBox1_Checked(object sender, RoutedEventArgs e)
    

    

任何人建议.......

【问题讨论】:

你有没有试过把ischeckboxchecked变成一个字符串,直接在里面放“true”或者“false”? 已关闭。请参阅我对链接问题的回答,以了解 WPF 的工作原理以及如何在多线程场景中正确使用 WPF UI 功能。 @HighCore 不是重复的;另一个问题中讨论的主题与本问题中提出的问题无关。如果它应该被标记为重复,那么应该附上一个广泛的评论来解释数据绑定如何可能或可能不是这里问题的解决方案。 @BasBrekelmans 抱歉,DataBinding 始终是 WPF 中类似 winforms 的东西背后可怕的非工作代码的解决方案。 real 这里的解决方案是删除所有可怕的代码并使用适当的 DataBinding。因此,我将关闭它以让 OP 阅读我对重复问题的回答并正确理解 WPF。 @HighCore 我同意你关于数据绑定的观点,尽管可能不是那么强烈。但是我觉得任何人都有权选择数据绑定是否是他们的解决方案,并且将其标记为重复是不正确的,因为它没有解决或解释 OP 提出的问题。 【参考方案1】:

您正在使用您的方法在调度程序上调用BeginInvokeBeginInvoke 立即返回。请改用Invoke 来获取阻塞调用,并仅在Dispatcher 操作完成后返回。

【讨论】:

从 beginInvoke 更改为 Invoke 解决了我的问题。感谢您的快速帮助 @BasBrekelmans 投票决定重新开放。但是,您没有说这在 WPF 中是一种非常糟糕的做法,而是在误导 OP,而他们应该使用 DataBinding。

以上是关于WPF 根据 UI 线程控制状态更新 NON UI 线程数据的主要内容,如果未能解决你的问题,请参考以下文章

多线程更新UI的常用方法

在具有 ui/非 ui 线程差异的 WPF 中使用 PInvoke

WPF Dispatcher.BeginInvoke子线程更新UI

富客户端 wpf, Winform 多线程更新UI控件

强制 WPF UI 线程更新任务

一种WPF在后台线程更新UI界面的简便方法