【问题标题】:Cross thread access problem in ResponseCallback in Windows Phone 7Windows Phone 7 ResponseCallback 中的跨线程访问问题
【发布时间】:2010-10-26 21:34:36
【问题描述】:

基本上,我从 WebService 获取一些数据,在 ResponseCallback 中,我试图用从响应中得到的结果填充 ObservableCollection,但我得到一个 UnauthorizedAccessException“无效的跨线程访问”当我尝试这样做时。

当我得到结果时,填充所述可观察集合的最佳方法是什么?

谢谢!

这是代码:

    public ObservableCollection<Person> People { get; set; }

    private void ResponseCallback(IAsyncResult asyncResult)
    {
        HttpWebRequest request = (HttpWebRequest)asyncResult.AsyncState;
        HttpWebResponse response = (HttpWebResponse)request.EndGetResponse(asyncResult);

        string responseString = string.Empty;

        using (Stream content = response.GetResponseStream())
        {
            if (request != null && response != null)
            {
                if (response.StatusCode == HttpStatusCode.OK)
                {
                    XDocument document = XDocument.Load(content);

                    var people = from p in document.Descendants()
                            where p.Name.LocalName == "PersonInfo"
                            select Person.GetPersonFromXElement(p);

                    foreach (Person person in people)
                    {
                        this.People.Add(person); // this line throws the exception
                    }
                }
            }

            content.Close();
        }
    }

【问题讨论】:

    标签: c# concurrency windows-phone-7


    【解决方案1】:

    我在 WP7 上遇到了完全相同的问题。它可以通过 Mick N 建议的代码来解决,无需从 DO 继承。只需从静态部署类中获取 Dispatcher。

    Deployment.Current.Dispatcher.BeginInvoke( () =&gt; { //your ui update code } );

    但这对我来说似乎是一种奇怪的解决方案,我从来不需要在桌面 Silverlight 中这样做。

    这是 WP7 特有的还是有更好的解决方案?谢谢。

    【讨论】:

    • 它是 WP7 特定的。我所做的是发送调用 ViewModel.Load() 方法的 UserControl 调度程序。它看起来像:App.MainViewModel.Load(this.Dispatcher);在内部我使用该调度程序进行异步操作,不确定它是否是最好的方法,但它可以工作。
    • 好吧,使用上面的方法,你不需要传递任何东西。在那个 Deployment 类中总是有一个 Dispatcher 等着你。无论哪种方式,这意味着由于我们的应用程序是基于互联网的,我们的代码将充满调度程序,对吗?
    • 好的,使用 WebClient 下载一切正常(绑定的 ObservableCollection 无需 Dispatcher 即可填充),但是当我使用 RestSharp lib(对于 WP7)时,我必须通过 Dispatcher 填充 ObsColl。
    【解决方案2】:

    【讨论】:

    • 感谢您的建议,但我不确定是否将此解决方案放入生产代码中。
    • 显然该解决方案在 Windows Phone 7 中不起作用。我并没有说这是我一开始使用的,但现在我将它添加到标题/标签中。谢谢。
    • 这是最接近的。它建议将 Dispatcher 发送到将执行异步操作的对象,这就是我所做的。谢谢!
    • 需要 WP7 解决方案而不是 WPF
    【解决方案3】:

    如果您想从另一个线程更新 UI(甚至间接通过观察到的集合),您只需要使用调度程序,如下所示:

    Dispatcher.BeginInvoke( () => { //your ui update code } );
    

    【讨论】:

    • 是的,问题是我发布的代码在我的视图模型中,我不想让我的视图模型仅仅为了这个而从 DependencyObject 继承。我们试图保持低内存,而 DependencyObject 非常耗费资源。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-05-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多