2014-02-17 83 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