Window.BeginInvoke()和Control.BeginInvoke()之间的区别是什么?

时间:2014-10-06 15:54:26

标签: c# .net wpf

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

// 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()?

1 个答案:

答案 0 :(得分:4)

来自Control.BeginInvoke

的文档
  

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

Thread.Sleep

的文档
  

暂停当前线程达到指定的时间。

WindowLabel都是在同一个线程(UI线程)上创建的。当您在该线程上调用Thread.Sleep()时(使用BeginInvoke),它会完全按照您的预期运行并导致线程被挂起(此线程负责监听Windows消息并保持UI& #34;响应"这就是你的应用冻结的原因)

我注意到你在一篇评论中写过

  

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

此问题的解决方案是不在UI线程上调用Sleep。您需要将长时间运行的任务交给单独的工作线程,而不是在UI线程上执行。考虑阅读Task Parallel Library以获得一种方法。

回答您的最新动态

  

如果我们可以更改windows.begininvoke()中的label1.content,为什么还需要label1.begininvoke()?

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