2010-10-26 1 views
8

Fondamentalement, j'obtiens des données d'un WebService, et dans le ResponseCallback j'essaye de remplir une ObservableCollection avec les résultats que j'ai obtenus de la réponse, mais je reçois un UnauthorizedAccessException "Accès au thread croisé non valide" lorsque j'essaie de le faire.Problème d'accès au thread croisé dans ResponseCallback dans Windows Phone 7

Quelle serait la meilleure façon de remplir cette collection observable lorsque j'obtiendrais le résultat?

Merci!

Voici le code:

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(); 
     } 
    } 

Répondre

2
+0

Merci pour la suggestion, mais je ne suis pas vraiment sûr de mettre cette solution dans le code de production. – Carlo

+0

Apparemment, la solution ne fonctionne pas dans Windows Phone 7. Je n'ai pas dit que c'était ce que j'utilisais au début, mais maintenant je l'ai ajouté au titre/tags. Merci. – Carlo

+0

gotcha. Je n'ai aucune expérience avec le téléphone 7 .. alors bonne chance! – climbage

1

Si vous souhaitez mettre à jour l'interface utilisateur (même indirectement par le biais d'une collection observée) d'un autre fil que vous venez besoin d'utiliser le répartiteur comme suit:

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

Ouais, le fait est que le code que j'ai posté est dans mon modèle de vue, et je ne veux pas que mon modèle de vue hérite de DependencyObject juste pour ça. Nous essayons de garder la mémoire faible, et DependencyObject sont très coûteux en ressources. – Carlo

14

J'ai exactement le même problème sur WP7. Il peut être résolu par le code Mick N suggéré et sans avoir besoin d'hériter de DO. Il suffit de prendre un Dispatcher à partir de la classe de déploiement statique.

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

Mais cela me semble bizarre sorte de solution, je l'ai jamais ont de le faire dans Silverlight de bureau.

Ce WP7 est-il spécifique ou existe-t-il une meilleure solution? Merci.

+0

C'est WP7 spécifique. Ce que j'ai fait, c'est que j'envoie le répartiteur de l'UserControl qui a appelé la méthode ViewModel.Load(). Cela ressemble à: App.MainViewModel.Load (this.Dispatcher); et à l'intérieur j'utilise ce répartiteur pour faire l'opération asynchrone, je ne sais pas si c'est la meilleure façon, mais ça fonctionne. – Carlo

+0

Eh bien, avec l'approche ci-dessus, vous n'avez pas besoin de passer quelque chose. Il y a toujours un Dispatcher qui vous attend dans cette classe de déploiement. De toute façon, cela signifie que, puisque nos applications sont basées sur Internet, notre code sera plein de Dispatchers, ai-je raison? – jumbo

+0

Ok, avec les téléchargements WebClient tout fonctionne bien (ObservableCollection lié est rempli sans besoin de Dispatcher), mais quand j'utilise RestSharp lib (pour WP7), je dois remplir le ObsColl via Dispatcher. – jumbo