Silverlight应用程序中的跨线程访问无效

Jim*_*eri 5 .net silverlight thread-safety hammock

我正在使用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);
}
Run Code Online (Sandbox Code Playgroud)

谢谢

Gon*_*ing 8

对于作为集合的绑定属性和属性(而不是可观察集合中的子集),只有OnPropertyChanged需要位于UI线程上.属性可以更早更改,但在调用OnPropertyChanged之前,UI不会更改绑定.

我们所有的ViewModel派生自我们创建的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);
    }
}
Run Code Online (Sandbox Code Playgroud)

如果您没有使用MVVM,a)道歉并且b)羞辱你:)