locked
Синхронизация 2х асинхронных запросов? RRS feed

  • Вопрос

  • Нужно получить список сообщений с именем пользователя и аватаркой отправителя... Приведенный ниже пример конечно же не работает,
    
    но из него понятно чего я собственно хочу добиться. Можно ли его как-нибудь поправить, чтобы работало?
    
    public void GetMessageList()
            {
                var c = new WebClient();
                string request;
               
    
                request = "https://api.vkontakte.ru/method/messages.get.xml?access_token=" + access_token + "&count=15";
                c.OpenReadCompleted += new OpenReadCompletedEventHandler(c_OpenReadCompleted);
                c.OpenReadAsync(new Uri(request));
    
            }
           
    
             void c_OpenReadCompleted(object sender, OpenReadCompletedEventArgs e)
            {
    
                XDocument xml = XDocument.Load(e.Result);
                IEnumerable<XElement> list = xml.Descendants("message");            
                XElement elem = xml.Root.Element("message");
                List<MessageList1> cflist = new List<MessageList1>();
             
               foreach (XElement node in list)
                {
    
                 GetFriendInfo(node.Element("uid").Value);  
                 cflist.Add(new MessageList1(node.Element("date").Value, node.Element("title").Value, node.Element("body").Value, friend_name, friend_photo));
                                  
                }
                 
                MessageList.ItemsSource = cflist;
            }
    
             public void GetFriendInfo(string friend_id)
             {
                 var c = new WebClient();
                 string request;
    
                 request = "https://api.vkontakte.ru/method/getProfiles.xml?access_token=" + access_token + "&uids=" + friend_id + "&fields=photo_rec";
                 c.OpenReadAsync(new Uri(request));
                 c.OpenReadCompleted += new OpenReadCompletedEventHandler(GetFriendInfoRe);
     
             }
    
             void GetFriendInfoRe(object sender, OpenReadCompletedEventArgs e)
             {
                 XDocument xml = XDocument.Load(e.Result);
                 XElement elem = xml.Root.Element("user");
                 friend_photo = elem.Element("photo_rec").Value;
                 friend_name = elem.Element("first_name").Value + " " +elem.Element("last_name").Value;
    
    
    
    
             }
    

    6 февраля 2012 г. 12:47

Ответы

  • Да, в ответе выше я упустил то, что Complete метод вызывается в главном потоке, и тем самым ожидание там вешает приложение.

    Тогда почему бы вам не использовать WebClient.OpenReadAsync Method (Uri, Object) в который в качестве 2го аргумента передавать объект MessageList1 (извлекать его потом из e.UserState) и дозополнять его в GetFriendInfoRe.


    Для связи [mail]

    • Помечено в качестве ответа Grizzzlly 8 февраля 2012 г. 22:06
    8 февраля 2012 г. 12:29

Все ответы

  • Можно использовать Mutex или ManualResetEvent (myEvent) и переменную счетчик (counter). Обявить их на уровне класса, чтоб иметь доступ из 2х callback-ов сразу.

    Перед MessageList.ItemsSource = cflist; ожидаем события от ManualResetEvent, т.е. вызываем myEvent.WaitOne(). Установка события будет происходить в конце функции GetFriendInfoRe - myEvent.Set(). Но также важно выполнить установку только для последнего сообщения, т.е. перед выполнением myEvent.Set() увеличивем counter на 1 с помощью функции Interlocked.Increment и проверяем равна ли она числу элементов, которые нужно загрузить.

    Возомжно не самое лучшее решение, но это то, что пришло с ходу.

     


    Для связи [mail]
    6 февраля 2012 г. 13:43
  • Ожидание должно быть между  GetFriendInfo(node.Element("uid").Value); и cflist.Add, у меня почему то в итоге вешается приложение... :-( Может не правильно пишу, можно пример, если не трудно?  
    6 февраля 2012 г. 15:24
  • Посмотрите здесь, может помочь: http://krez0n.org.ua/archives/686
    7 февраля 2012 г. 7:15
  • Да, в ответе выше я упустил то, что Complete метод вызывается в главном потоке, и тем самым ожидание там вешает приложение.

    Тогда почему бы вам не использовать WebClient.OpenReadAsync Method (Uri, Object) в который в качестве 2го аргумента передавать объект MessageList1 (извлекать его потом из e.UserState) и дозополнять его в GetFriendInfoRe.


    Для связи [mail]

    • Помечено в качестве ответа Grizzzlly 8 февраля 2012 г. 22:06
    8 февраля 2012 г. 12:29