如何理解WP中源代码"UI Thread"覆盖范围



我想知道是否可以根据Windows Phone开发中的静态分析,从源代码中了解哪些代码段在UI上执行。

我尝试实现一个静态分析,查找Dispatcher所在的位置。(Begin)Invoke被不必要地使用。

这些是UI线程肯定执行的地方:

  • 获取"RoutedEventArgs"作为参数的事件处理程序
  • UI元素的构造函数
  • 上述方法中方法调用的定义(意味着可以转换地查看这些事件处理程序方法和UI构造函数的调用图)

上面的清单还有其他地方吗?或者有什么不对的地方吗?

使用Dispatcher或正确的SynchronizationContext调用的每个方法都将在UI线程上执行。这使得详尽的静态分析变得不可能。例如,WebClient类的回调在UI线程上执行。你应该如何预测那些角落的情况?

不过,一个非常有用的快速提示是,您有一个可以从UI或非UI线程调用的方法。通过调用方法Dispatcher.CheckAccess()(Visual Studio中的intellisense没有显示此方法,因此很难发现),您可以知道是否需要调用Dispatcher:

if (Dispatcher.CheckAccess())
{
    // In the UI thread
    SomeMethod();
}
else
{
    // Not in the UI thread
    Dispatcher.BeginInvoke(SomeMethod);
}

从那里,你可以编写一个包装器:

public void CallDispatcherIfNeeded(Action method) // You might want a shorter name
{
    if (Dispatcher.CheckAccess())
    {
        // In the UI thread
        method();
    }
    else
    {
        // Not in the UI thread
        Dispatcher.BeginInvoke(method);
    }
}

然后你只需要调用它,而不用担心你是否在UI线程上:

CallDispatcherIfNeeded(SomeMethod);

也就是说,如果你的代码写得正确,那么很少需要这种技巧。

我会看看什么时候真正需要Dispatcher.BeginInvoke,而不是相反。

它几乎从来都不需要,除非处理可能在后台线程上开始的异步完成事件,因此,如果您想对UI执行某些操作,则需要将其封送到UI线程。

换句话说,除非你需要从后台线程对UI做些什么,否则你不需要它

Greg

最新更新