C# 使用DispatcherObject的VerifyAccess和CheckAccess方法

C# 使用DispatcherObject的VerifyAccess和CheckAccess方法,c#,wpf,silverlight,custom-controls,dispatcher,C#,Wpf,Silverlight,Custom Controls,Dispatcher,在阅读这篇文章时,我偶然发现了这句话- 如果您正在编写自己的WPF 对象,例如控件、所有方法 您应该使用调用VerifyAccess 在他们做任何工作之前。这 保证您的对象仅为 在UI线程上使用,如下所示 我在遇到的任何自定义控件中都没有看到过这种情况(据我记忆所及) 在构建自定义控件时是否使用此选项 一定要这样做,还是拥有它就好 有没有人因为在你的控制中没有这一点而面临过任何问题 不,从来没有用过这个。从未注意到有人在自定义控件的上下文中使用它。WPF工具包中也不遵循此规则 这种方法不仅污染

在阅读这篇文章时,我偶然发现了这句话-

如果您正在编写自己的WPF 对象,例如控件、所有方法 您应该使用调用VerifyAccess 在他们做任何工作之前。这 保证您的对象仅为 在UI线程上使用,如下所示

我在遇到的任何自定义控件中都没有看到过这种情况(据我记忆所及)

  • 在构建自定义控件时是否使用此选项
  • 一定要这样做,还是拥有它就好
  • 有没有人因为在你的控制中没有这一点而面临过任何问题

  • 不,从来没有用过这个。从未注意到有人在自定义控件的上下文中使用它。WPF工具包中也不遵循此规则

    这种方法不仅污染了代码,而且使您的自定义控件负责一些它不应该关心的事情。考虑一下你一直在做的情况:

    // Don't do this in all methods of your custom control!
    public void Foo()
    {
      if (!CheckAccess())
      {
        Dispatcher.Invoke(()=> Foo()); // Transit to UI Thread
        return;
      }
      // .. do work in UI.
    }
    
    乍一看,这段代码看起来不错。若您不在UI线程中,则转换到UI线程,执行操作并返回结果。对吧?错了

    问题1。当您调用
    Dispatcher.Invoke()
    时,您会阻止调用线程,直到UI线程处理您的请求。这会导致性能不佳。当然,您可以将其更改为
    Dispatcher.BeginInvoke()
    ,现在您的客户机应该知道他们的操作是异步完成的。也就是说,如果客户端向控件写入某个内容,然后立即将其读回,则无法保证UI线程已执行该操作

    <强>问题2。< /强>考虑从非UI线程对方法<代码>脚注()/代码>的后续调用。例如,它在循环中被称为:

    // Somewhere not in UI
    for (int i = 0; i < 1000000; i++)
    {
      control.Foo(); // Looks good, but performance is awful!
    }
    
    //不在UI中的某个地方
    对于(int i=0;i<1000000;i++)
    {
    control.Foo();//看起来不错,但性能很差!
    }
    
    开发人员可以在调用线程中实现一次检查,并在必要时转换到UI,而不是无意识地在线程之间跳回和切换,而不是阻止调用线程1000000次

    此外,当您从非UI线程访问UI元素时,WPF将为您进行此检查。它的尖叫声足以粉碎应用程序,让犯了错误的开发人员听到:)


    希望这有帮助。

    是的,这很有帮助。我只是想知道我是否是唯一一个没有使用它并且遗漏了一些东西的人。谢谢
    // Somewhere not in UI
    for (int i = 0; i < 1000000; i++)
    {
      control.Foo(); // Looks good, but performance is awful!
    }