什么';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?
来自Control.BeginVoke 的文档
在创建控件的基础句柄的线程上异步执行指定的委托。
Thread.Sleep 的文档
将当前线程挂起指定的时间。
Window
和Label
都是在同一个线程(UI线程)上创建的。当您在该线程上调用Thread.Sleep()
(使用BeginInvoke
)时,它会完全按照您的期望执行,并导致线程挂起(该线程负责侦听windows消息并保持UI"响应",这就是应用程序冻结的原因)
我注意到,在你的一条评论中,你写了
@alykins,因为这意味着有一些方法需要很多时间,我不会让主UI线程卡在那里。
这个问题的解决方案是不在UI线程上调用Sleep
。您需要将长时间运行的任务交给一个单独的工作线程,而不是在UI线程上执行。考虑阅读任务并行库中的一种方法。
回答您的最新更新
如果我们可以在windows.begininvoke()中更改label1.content,为什么我们仍然需要label1.beginnvoke?
在Label
和Window
由单独的线程(而不是UI线程)创建和拥有的不太可能的情况下,您将使用Label.BeginInvoke()
来更新Label
,而Window.BeginInvoke()
将不起作用。