什么';s Window.BeginInvoke()和Control.BeginInvoke()之间的区别

本文关键字:BeginInvoke Control 之间 区别 Window 什么 | 更新日期: 2023-09-27 18:25:51

我需要更改标签内容。但是代码在执行之前会休眠。那么我使用窗口执行代码或使用控件本身有什么不同呢?类似:

// Use Label execute
Label1.BeginInvoke(new Action(()=>{
         System.Thread.Thread.Sleep(5000);
         Label1.Content = "New Value";
});
// Use Window execute
MainWindow.BeginInvoke(new Action(()=>{
         System.Thread.Thread.Sleep(5000);
         Label1.Content = "New Value";
});

无论我使用Label还是Window,它总是在线程休眠时卡住UI。为什么?为什么当我们执行label.BeginInvoke()时它不冻结标签,如果没有任何不同,为什么Microsoft不删除Control.BeginInvoke(

更新1:很抱歉睡眠(5000),我只是告诉你,在更改标签内容之前,有一种方法需要很长时间才能执行。

更新2所以,如果没有任何不同,那么Control2.BeginInvoke()和Control3.BeginInvoke.()没有什么不同吗?那为什么微软不只保留Window.Begininvoke()呢?

更新3为什么我可以更改Control3.BeginInvoke中的Control2.Content?如果没有限制,为什么所有人都有那个方法?为何

更新4也许Update2-3是一个伪问题,很抱歉,我的意思是:如果我们可以在windows.begininvoke()中更改label1.content,为什么我们仍然需要label1.beginnvoke?

什么';s Window.BeginInvoke()和Control.BeginInvoke()之间的区别

来自Control.BeginVoke 的文档

在创建控件的基础句柄的线程上异步执行指定的委托。

Thread.Sleep 的文档

将当前线程挂起指定的时间。

WindowLabel都是在同一个线程(UI线程)上创建的。当您在该线程上调用Thread.Sleep()(使用BeginInvoke)时,它会完全按照您的期望执行,并导致线程挂起(该线程负责侦听windows消息并保持UI"响应",这就是应用程序冻结的原因)

我注意到,在你的一条评论中,你写了

@alykins,因为这意味着有一些方法需要很多时间,我不会让主UI线程卡在那里。

这个问题的解决方案是不在UI线程上调用Sleep。您需要将长时间运行的任务交给一个单独的工作线程,而不是在UI线程上执行。考虑阅读任务并行库中的一种方法。

回答您的最新更新

如果我们可以在windows.begininvoke()中更改label1.content,为什么我们仍然需要label1.beginnvoke?

LabelWindow由单独的线程(而不是UI线程)创建和拥有的不太可能的情况下,您将使用Label.BeginInvoke()来更新Label,而Window.BeginInvoke()将不起作用。