我正在开发一个可在Windows 8.1和Windows上运行的通用应用。 Windows Phone 8.1。在较旧的基于Silverlight的Windows Phone应用程序中,我可以在我的View Model上找到一个方便的帮助器:
protected delegate void OnUIThreadDelegate();
protected static void OnUIThread(OnUIThreadDelegate onUIThreadDelegate)
{
if (onUIThreadDelegate != null)
{
if (Deployment.Current.Dispatcher.CheckAccess())
{
onUIThreadDelegate();
}
else
{
Deployment.Current.Dispatcher.BeginInvoke(onUIThreadDelegate);
}
}
}
从我所看到的使用async
我should be able做以下事情:
async void Watcher_PositionChanged(Geolocator sender, PositionChangedEventArgs args)
{
this.Latitude = args.Position.Coordinate.Point.Position.Latitude;
this.Longitude = args.Position.Coordinate.Point.Position.Longitude;
// TODO: Consider reloading;
var ev = await SpecialEvent.SearchNearAsync();
this.Events.Clear(); // this is an ObservableCollection that the XAML is bound to,
// and I'm seeing it blow up with RPC_E_WRONG_THREAD here
}
使用Dispatcher
的其他选项似乎更难,因为在通用应用中,Application.Current
没有Dispatcher
属性?
那剩下的选择是什么?我是否必须更改我的View-Models以允许从View传递调度程序,或者我错过了一些更明显的东西?
答案 0 :(得分:4)
您可以使用:
从任何主题获取调度程序var dispatcher = CoreApplication.MainView.CoreWindow.Dispatcher;
关于异步 - 它的作用是在另一个线程中调用(等待)等待的方法,当它完成时,返回第一个线程并继续执行。因此,在您的情况下,Watcher_PositionChanged方法不会在UI线程中调用,因此它无法访问UI元素。
注意(关于一般的异步):如果您有异步方法,则不会在另一个线程中自动调用它。如果要在不同的线程中执行其中的一部分,则必须手动告诉它这样做。否则它很容易同步。此外,在等待时,您可以将其配置为在第二个线程上继续 - 为异步工作创建的线程。