0xD*_*EEF 1 user-interface multithreading mvvm microsoft-metro windows-runtime
我有工人阶级
public event EventHandler<EventArgs> DataModified;
Run Code Online (Sandbox Code Playgroud)
可以从UI线程之外引出(它是从服务器获取更新的网络客户端).我有ModelView
ObservableCollection<DataModel> DataItems;
Run Code Online (Sandbox Code Playgroud)
视图绑定到哪个.我的modelview必须订阅ModifiedEvent,因此它可以反映DataItems中的更改.如何从回调事件更新DataItems?我无法从模型视图访问UI Dispatcher(因为视图不应该知道模型视图).什么是正确的.NET 4.5方式来处理这个?
您可以创建一个服务,它可以保存CoreDispatcher并注入您的视图模型(或使其静态)
public static class SmartDispatcher
{
private static CoreDispatcher _instance;
private static void RequireInstance()
{
try
{
_instance = Window.Current.CoreWindow.Dispatcher;
}
catch (Exception e)
{
throw new InvalidOperationException("The first time SmartDispatcher is used must be from a user interface thread. Consider having the application call Initialize, with or without an instance.", e);
}
if (_instance == null)
{
throw new InvalidOperationException("Unable to find a suitable Dispatcher instance.");
}
}
public static void Initialize(CoreDispatcher dispatcher)
{
if (dispatcher == null)
{
throw new ArgumentNullException("dispatcher");
}
_instance = dispatcher;
}
public static bool CheckAccess()
{
if (_instance == null)
{
RequireInstance();
}
return _instance.HasThreadAccess;
}
public static void BeginInvoke(Action a)
{
if (_instance == null)
{
RequireInstance();
}
// If the current thread is the user interface thread, skip the
// dispatcher and directly invoke the Action.
if (CheckAccess())
{
a();
}
else
{
_instance.RunAsync(CoreDispatcherPriority.Normal, () => { a(); });
}
}
}
Run Code Online (Sandbox Code Playgroud)
您应该在App.xaml.cs中初始化SmartDispatcher:
var rootFrame = new Frame();
SmartDispatcher.Initialize(rootFrame.Dispatcher);
Window.Current.Content = rootFrame;
Window.Current.Activate();
Run Code Online (Sandbox Code Playgroud)
以这种方式使用它:
SmartDispatcher.BeginInvoke(() => _collection.Add(item));
Run Code Online (Sandbox Code Playgroud)
本课程基于Jeff Wilcox的Windows Phone 7模拟.