【问题标题】:Creating a task for wcf Async, doesnt await为 wcf 异步创建任务,不等待
【发布时间】:2014-02-17 00:27:46
【问题描述】:

基本上,当我的自动完成文本框更改文本时,它会从WCF 服务更新(附照片),问题是:

Task taskA = new Task(() => listanomes.queryAsync(argumentos, 2, 3, query));

任务没有一开始就开始,所以我需要的列表是空的。

private async void tbA_destinatario_TextChanged(object sender, RoutedEventArgs e)
{
    await buscaAC();
    await fotos();
    int i = 0;
    foreach (Pessoa temp in listaPessoas)
    {
        if (listaimgs.Count == 0)
            break;
        temp.Imagem = listaimgs[i];
        i++;
        listaPessoas[i] = temp;
    }
    tbA_destinatario.ItemsSource = listaPessoas;
}

private async Task buscaAC()
{
    ServicosLinkedIN.ServicosClient listanomes = new ServicosLinkedIN.ServicosClient();
    string query = "select nome,id_user, foto from tbl_conexoes, tbl_users where((tbl_conexoes.id_con2 = @var1 AND id_con1 = id_user) OR (tbl_conexoes.id_con1 = @var1 AND id_con2 = id_user)) AND upper(nome) LIKE upper(@var2)  ORDER BY nome LIMIT 0, 5";
    List<string> argumentos = new List<string>();
    argumentos.Add(Convert.ToString(id));
    argumentos.Add("%" + tbA_destinatario.Text + "%");

    //listanomes.listautilizadoresAsync(id, tbA_destinatario.Text);
    listanomes.queryCompleted += listanomesautocomplete;
    Task taskA = new Task(() => listanomes.queryAsync(argumentos, 2, 3, query));
    taskA.Start();
    await taskA;
}

private async Task fotos()
{
    ServicosLinkedIN.ServicosClient dlfotos = new ServicosLinkedIN.ServicosClient();

    dlfotos.listadlFotoCompleted += dlfotos_listadlFotoCompleted;
    Task taskA = new Task(() => dlfotos.listadlFotoAsync(nomeimgs));
    taskA.Start();

    await taskA;
}

【问题讨论】:

  • 使用async-await 仅使用Task.Run 来启动任务。在 C# 中,方法始终是 CamelCased,异步方法应以 Async 为后缀。为什么不对 WCF 使用异步代理?

标签: c# wcf asynchronous task async-await


【解决方案1】:

如果不尝试进一步分析您的代码,这肯定是一个问题:

Task taskA = new Task(() => listanomes.queryAsync(argumentos, 2, 3, query));

你在这里做的是“一劳永逸”。当您开始您的任务时,它会立即完成,而queryAsync 将继续在后台执行。

你应该重写你的代码而不显式使用Task 构造函数。我相信这是可能的。

【讨论】:

  • 它没有完成,我的任务完成时应该填写的列表仍然是空的。当我调试时,该任务仅在 tbA_destinatario_TextChanged 完成后开始。无论如何,谢谢!
  • @外部任务 did,然后您使用 listanomes.queryAsync() 创建的内部任务 not。要明白我的意思,试试这个:Task taskA = new Task(() =&gt; listanomes.queryAsync(argumentos, 2, 3, query).Wait()),注意Wait()。这是为了让您理解问题,但是像这样使用Wait() 也是一种代码异味。
  • 我不太明白你的意思,但我试过那个代码,结果是一样的,我不能等待一个 void 函数。这种情况有什么解决办法吗?
  • @user3285630,您在代码的哪一行看到“无法等待 void”?
  • 正是我为 taskA 使用 await 的那一行。例如:Task taskA = new Task( async () => await listanomes.queryAsync(argumentos, 2, 3, query));但如果我 taskA.Start();然后等待任务A;它没有给出任何错误,但它也不起作用。
【解决方案2】:

我认为您将不得不等待您在代表内部调用的任务。例如:

Task taskA = new Task( async () => await listanomes.queryAsync(argumentos, 2, 3, query));

但我真的不明白为什么要创建一个单独的任务。你可以使用:

await listanomes.queryAsync(argumentos, 2, 3, query);

与其创建taskA,不如启动它并等待它。

【讨论】:

  • 不能等待'void'同时使用这两种解决方案,感谢您的回复
  • 好吧,我假设方法返回 Task,因为命名约定表明,当方法名称以 Async 结尾时,它意味着它返回 Task。
  • new Task( async () =&gt; await listanomes.queryAsync(..)) 与new Task(() =&gt; listanomes.queryAsync(..)) 几乎相同。你是对的,虽然 OP 根本不需要创建外部 Task。
  • 是的,我是这个意思。我认为方法设计有问题。
  • 好吧,如果我执行 listanomes.queryAsync(..),则列表(应该在完成时填写该 queryasync)为空,因为它只会在 tbA_destinatario_TextChanged 完成后执行 queryasync
猜你喜欢
  • 1970-01-01
  • 2016-01-15
  • 2014-03-18
  • 1970-01-01
  • 2014-09-06
  • 2013-02-10
  • 2017-07-22
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多