首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >APM模式,等待异步

APM模式,等待异步
EN

Stack Overflow用户
提问于 2014-02-17 02:55:33
回答 2查看 352关注 0票数 1

我需要关于如何使用APM模式的帮助,我现在正在阅读一些文章,但我恐怕没有太多的时间。我真正想要的是获取所有人员(来自db的数据),然后获取照片并将其放在自动完成框代码中:

代码语言:javascript
运行
复制
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";
            }
        }
EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2014-02-17 03:40:24

这里有几件事要解决:

  • listanomesautocomplete事件处理程序应该是async。处理并报告在其中可能抛出的所有异常(通常,此规则适用于任何事件处理程序,但它对async事件处理程序更为重要,因为处理程序中的异步操作在触发事件的代码范围之外继续进行)。
  • 首先注册dlFotoCompleted事件处理程序,然后调用dlFotoAsync。不要假设dlFotoAsync总是异步执行的。
  • 考虑一下当另一个listanomesautocomplete在上一次操作仍未完成时被触发的情况。这种情况可能是用户操作的结果。您可能希望取消并重新启动挂起的操作(如),或者在挂起的操作完成后立即排队执行一个新的操作(如)。

回到问题上,您需要将EAP模式包装为Task,而不是APM。为此请使用TaskCompletionSource。代码的相关部分可能如下所示:

代码语言:javascript
运行
复制
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";
    }
}
票数 1
EN

Stack Overflow用户

发布于 2014-02-17 04:22:29

代码语言:javascript
运行
复制
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";
            }
        }

伙计,我一点也不生气,我很惊讶。诺塞雷肖,你的回答给了我一个主意,它确实奏效了!!非常感谢,伙计,我不能再感谢你了;)

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/21819937

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档