我想知道是否可以根据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