2014-02-17 78 views
1

我需要關於如何使用APM模式的幫助,我現在正在閱讀一些文章,但我恐怕沒有太多時間。我真正想要的是讓所有的人(從數據庫中的數據),那麼得到的照片,並把它放在一個autocompletebox 代碼:APM模式,等待異步

void listanomesautocomplete(object sender, ServicosLinkedIN.queryCompletedEventArgs e) 
     { 
      if (e.Result[0] != "") 
      { 
       for (int i = 0; i < e.Result.Count(); i = i + 3) 
       { 
        Pessoa pessoa = new Pessoa(); 
        pessoa.Nome = e.Result[i]; 
        pessoa.Id = Convert.ToInt32(e.Result[i + 1]); 
        if (e.Result[i + 2] == "") 
         pessoa.Imagem = new BitmapImage(new Uri("Assets/default_perfil.png", UriKind.Relative)); 
        else 
        { 
         ServicosLinkedIN.ServicosClient buscaimg = new ServicosLinkedIN.ServicosClient(); 
         buscaimg.dlFotoAsync(e.Result[i + 2]); 
         buscaimg.dlFotoCompleted += buscaimg_dlFotoCompleted;//when this completes it saves into a public bitmapimage and then i save it into pessoa.Imagem 
         //basicly, what happends, the listadlfotosasync only happends after this function 
         //what i want is to wait until it completes and have into the class novamsg 
         pessoa.Imagem = img;//saving the photo from dlFotoAsync   

        } 
        listaPessoas.Add(pessoa); 
       } 

       tbA_destinatario.ItemsSource = null; 
       tbA_destinatario.ItemsSource = listaPessoas; 

       BackgroundWorker listapessoas = new BackgroundWorker(); 
       listapessoas.DoWork += listapessoas_DoWork; 
       listapessoas.RunWorkerAsync(); 
       tb_lerdestmsg.Text = ""; 
      } 
      else 
      { 
       tbA_destinatario.ItemsSource = null; 
       tb_lerdestmsg.Text = "Não encontrado"; 
      } 
     } 
+0

我需要的是這個 http://stackoverflow.com/questions/18753719/how-to-await-for-querycompleted-event或(thesame )http://extensionmethod.net/csharp/dataservicequery-tresult/queryasync – user3285630

回答

1

有解決這裏的幾件事情:

  • listanomesautocomplete事件處理程序應該是async。處理並報告可能拋出的所有異常(通常,這條規則適用於任何事件處理程序,但對於事件處理程序更重要,因爲處理程序內的異步操作會持續到觸發事件的代碼範圍之外) 。

  • 先註冊dlFotoCompleted事件處理程序,然後調用dlFotoAsync。不要假設dlFotoAsync將是總是異步執行。

  • 想想在另一個listanomesautocomplete被激活而前一個操作仍在等待時的情況。這個井可能會由於用戶的行爲而發生。您可能需要取消並重新啓動掛起的操作(如this),或者只要掛起掛起的掛鉤(如this)就立即排隊新的掛起操作。

回到問題,那就是你需要用爲Task,不APM的EAP pattern。爲此,使用TaskCompletionSource。你的代碼的相關部分可能看起來是這樣的:

async void listanomesautocomplete(object sender, ServicosLinkedIN.queryCompletedEventArgs e) 
{ 
    if (e.Result[0] != "") 
    { 
     for (int i = 0; i < e.Result.Count(); i = i + 3) 
     { 
      Pessoa pessoa = new Pessoa(); 
      pessoa.Nome = e.Result[i]; 
      pessoa.Id = Convert.ToInt32(e.Result[i + 1]); 
      if (e.Result[i + 2] == "") 
       pessoa.Imagem = new BitmapImage(new Uri("Assets/default_perfil.png", UriKind.Relative)); 
      else 
      { 
       // you probably want to create the service proxy 
       // outside the for loop 
       using (ServicosLinkedIN.ServicosClient buscaimg = new ServicosLinkedIN.ServicosClient()) 
       { 
        FotoCompletedEventHandler handler = null; 
        var tcs = new TaskCompletionSource<Image>(); 

        handler = (sHandler, eHandler) => 
        { 
         try 
         { 
          // you can move the code from buscaimg_dlFotoCompleted here, 
          // rather than calling buscaimg_dlFotoCompleted 
          buscaimg_dlFotoCompleted(sHandler, eHandler); 

          tcs.TrySetResult(eHandler.Result); 
         } 
         catch (Exception ex) 
         { 
          tcs.TrySetException(ex); 
         } 
        }; 

        try 
        { 
         buscaimg.dlFotoCompleted += handler; 
         buscaimg.dlFotoAsync(e.Result[i + 2]); 

         // saving the photo from dlFotoAsync 
         pessoa.Imagem = await tcs.Task; 
        } 
        finally 
        { 
         buscaimg.dlFotoCompleted -= handler; 
        } 
       } 
      } 
      listaPessoas.Add(pessoa); 
     } 

     tbA_destinatario.ItemsSource = null; 
     tbA_destinatario.ItemsSource = listaPessoas; 

     BackgroundWorker listapessoas = new BackgroundWorker(); 
     listapessoas.DoWork += listapessoas_DoWork; 
     listapessoas.RunWorkerAsync(); 
     tb_lerdestmsg.Text = ""; 
    } 
    else 
    { 
     tbA_destinatario.ItemsSource = null; 
     tb_lerdestmsg.Text = "Não encontrado"; 
    } 
} 
0
void listanomesautocomplete(object sender, ServicosLinkedIN.queryCompletedEventArgs e) 
     { 

      if (e.Result[0] != "") 
      { 

       List<Pessoa> listaPessoas = new List<Pessoa>(); 

       for (int i = 0; i < e.Result.Count(); i = i + 3) 
       { 
        Pessoa pessoa = new Pessoa(); 
        pessoa.Nome = e.Result[i]; 
        pessoa.Id = Convert.ToInt32(e.Result[i + 1]); 
        if (e.Result[i + 2] == "") 
         pessoa.Imagem = new BitmapImage(new Uri("Assets/default_perfil.png", UriKind.Relative)); 
        else 
        { 
         ServicosLinkedIN.ServicosClient buscaimg = new ServicosLinkedIN.ServicosClient(); 
         buscaimg.dlFotoAsync(e.Result[i + 2]); 
         //THIS ACTUALLY WORKS!!! 
         //THE THREAD WAITS FOR IT! 
         buscaimg.dlFotoCompleted += (s, a) => 
         { 
          pessoa.Imagem = ConvertToBitmapImage(a.Result); 
         }; 
        } 
        listaPessoas.Add(pessoa); 
       } 

       if (tbA_destinatario.ItemsSource == null) 
       { 

        tbA_destinatario.ItemsSource = listaPessoas; 
       } 
       tb_lerdestmsg.Text = ""; 
      } 
      else 
      { 
       tbA_destinatario.ItemsSource = null; 
       tb_lerdestmsg.Text = "Não encontrado"; 
      } 
     } 

人,我都不生氣,我很驚訝。 Noseratio,你回答給了我一個想法,它實際上工作! 非常感謝很多人,我不能感謝你足夠;)

+0

沒問題,但是這段代碼仍然不正確。想想如果在調用'dlFotoAsync'後1秒內激發'dlFotoCompleted'會發生什麼。到那時''循環可能會完成。 – Noseratio

+0

不可能我想,我測試的方式,只有1個線程完成了所有的工作,但我會一直強調程序,再一次感謝您的時間! – user3285630

+0

有些事情是錯誤的...我完全複製其他頁面上的代碼,它不起作用。 (tbA_destinatario.ItemsSource == null) tbA_destinatario.ItemsSource = listaPessoas;如果(tbA_destinatario.ItemsSource == null)我觀察了正在進行的調試以及它的非常神奇的功能。 }如果你檢查上面的代碼是沒有意義的嗎?在對itemsource進行第一次更新之後,它不應該再起作用了......但是,我已經通過'tbA_destinatario.ItemsSource'檢查了整個解決方案,並且沒有出現任何內容,有些內容正在填充tbA_destinatario.ItemsSource,我不知道是什麼。 – user3285630