Заполнение списка WP7 из веб-сервиса приводит к «Недопустимому межпоточному доступу».

#windows-phone-7

#windows-phone-7

Вопрос:

Извините, если это простой вопрос, но я совершенно новичок в WP7. У меня есть служба rest, которую я пытаюсь использовать, однако я получаю сообщение об ошибке «Недопустимый межпоточный доступ».

Это мой код

    public ObservableCollection<TransactionViewModel> Transactions { get;private set; }
   public MainViewModel()
    {
        this.Transactions = new ObservableCollection<TransactionViewModel>();
    }
    public void LoadTransactions(string id)
    {
        var req = (HttpWebRequest)WebRequest.Create(string.Format("http://domain.com/Transactions?Id={0}", id));
            req.Method = "POST";
            req.ContentType = "application/json; charset=utf-8";

           // call async
            req.BeginGetResponse(new AsyncCallback(jsonGetRequestStreamCallback), req);


        this.IsDataLoaded = true;

    }

    void jsonGetRequestStreamCallback(IAsyncResult asynchronousResult)
    {

        WebResponse response = ((HttpWebRequest)asynchronousResult.AsyncState).EndGetResponse(asynchronousResult);
        using (StreamReader reader = new StreamReader(response.GetResponseStream()))
        {
            string responseString = reader.ReadToEnd();
            reader.Close();


            var s = JsonConvert.DeserializeObject<List<TransactionViewModel>>(responseString);

            foreach (var t in s)
            {
                Transactions.Add(new TransactionViewModel()
                                     {
                                      .........
                                     }
            }
  

Я сделал здесь что-то действительно глупое?

Ответ №1:

Когда вы возвращаетесь из запроса, вы больше не находитесь в потоке пользовательского интерфейса. Поэтому вам необходимо переключить управление обратно на поток пользовательского интерфейса, прежде чем выполнять какие-либо действия, которые повлияют на пользовательский интерфейс.

Вы обновляете ObservableCollection, который будет привязан к пользовательскому интерфейсу, и, следовательно, обновление повлияет на пользовательский интерфейс.

Существует ряд подходов, наиболее простым для ваших целей будет

 Deployment.Current.Dispatcher.BeginInvoke(()=> {
 foreach (var t in s) {
  Transactions.Add(new TransactionViewModel());
 }
});
  

Редактировать: Также, если вы хотите прочитать немного больше об этом, у меня есть сообщение в блоге об этом здесьhttp://csainty.blogspot.com/2010/10/windows-phone-7asynchronous-programming.html он начинается с кода, подобного вашему, который выглядит разумным и должен работать, объясняет несколько ошибок и как заставить его работать.

Комментарии:

1. Спасибо, Крис, за вашу помощь и ссылку 🙂