我需要更改标签内容。但代码将在执行之前休眠。那么我使用窗口执行代码或使用控件本身的不同之处是什么?像:
// 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不删除控件的Mothod.Begininvoke()
UPDATE1: 对于睡眠(5000),我只是告诉您,在更改标签内容之前,有一种方法需要花费很多时间才能执行。
UPDATE2 那么如果没有任何不同,那么与Control2.BeginInvoke()和Control3.BeginInvoke()没有什么不同? 那么为什么微软不仅仅保留Window.Begininvoke()?
UPDATE3 为什么我可以在Control3.BeginInvoke中更改Control2.Content?如果没有限制为什么All都有这种方法?为什么?
UPDATE4 也许Update2-3是虚拟的qustion,对不起,我的意思是:如果我们可以更改中的label1.begininvoke()中的label1.content ,为什么我们仍然需要label1.begininvoke()?
答案 0 :(得分:4)
的文档在创建控件的基础句柄的线程上异步执行指定的委托。
暂停当前线程达到指定的时间。
Window
和Label
都是在同一个线程(UI线程)上创建的。当您在该线程上调用Thread.Sleep()
时(使用BeginInvoke
),它会完全按照您的预期运行并导致线程被挂起(此线程负责监听Windows消息并保持UI& #34;响应"这就是你的应用冻结的原因)
我注意到你在一篇评论中写过
@alykins,因为这意味着有一些方法需要很多时间,而且我不会让主UI线程卡在那里。
此问题的解决方案是不在UI线程上调用Sleep
。您需要将长时间运行的任务交给单独的工作线程,而不是在UI线程上执行。考虑阅读Task Parallel Library以获得一种方法。
回答您的最新动态
如果我们可以更改windows.begininvoke()中的label1.content,为什么还需要label1.begininvoke()?
在不太可能的情况下,Label
和Window
是由不同的线程(而不是UI线程)创建和拥有的,您可以使用Label.BeginInvoke()
更新Label
}和Window.BeginInvoke()
不起作用。