我正在使用 Hammock 框架从 Silverlight 应用程序到 Rest 服务进行异步服务调用。在“完成”回调中,我正在更新绑定到视图上组合框的 ObservableCollection。
“OnPropertyChanged”事件处理程序中抛出“无效的跨线程访问”异常。
这是因为 Hammock 没有在 UI 线程上执行回调吗?如果没有,为什么不呢?这似乎是框架应该处理的功能。我错过了什么吗?我确实不想在每个已完成的处理程序中自己处理 UI 线程的调用。
public void LoadMyData()
{
var request = new RestRequest();
request.Path = "MyRestUrlText";
var callback = new RestCallback(
(restRequest, restResponse, userState) =>
{
var visibleData = new ObservableCollection<MyDataType>();
var myData = JsonConvert.DeserializeObject<MyDataType[]> restResponse.Content);
foreach (var item in myData)
visibleData .Add(item);
this.MyBoundCollection = visibleData;
OnPropertyChanged("MyBoundCollection");
});
var asyncResult = _restClient.BeginRequest(request, callback);
}
Thanks
对于绑定属性和集合属性(而不是可观察集合中的子属性),只有 OnPropertyChanged 需要位于 UI 线程上。属性可以提前更改,但在调用 OnPropertyChanged 之前,UI 不会更改绑定。
我们所有的 ViewModel 都派生自我们创建的 ViewModelBase,该 ViewModelBase 实现了如下所示的助手 SendPropertyChanged (因此我们永远不必担心跨线程)。
我们所有的通知属性都会调用它,而不是直接调用 OnPropertyChanged。
它还公开了一个通常有用的 OnUiThread 方法,以便您可以在 UI 线程上执行任意代码:
protected delegate void OnUiThreadDelegate();
public event PropertyChangedEventHandler PropertyChanged;
public void SendPropertyChanged(string propertyName)
{
if (this.PropertyChanged != null)
{
this.OnUiThread(() => this.PropertyChanged(this, new PropertyChangedEventArgs(propertyName)));
}
}
protected void OnUiThread(OnUiThreadDelegate onUiThreadDelegate)
{
if (Deployment.Current.Dispatcher.CheckAccess())
{
onUiThreadDelegate();
}
else
{
Deployment.Current.Dispatcher.BeginInvoke(onUiThreadDelegate);
}
}
如果您不使用 MVVM,a) 抱歉,b) 对您感到羞耻:)
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)