【问题标题】:Creating an typed async Task创建一个类型化的异步任务
【发布时间】:2016-12-10 00:17:19
【问题描述】:

我现在想创建一些异步任务而不启动它们。 使用无类型任务没有问题:

    private Task CreateTask() {
        return new Task(
             async () => await DoSomething().ConfigureAwait(false));
    }

但是为了处理异常,我在函数中添加了一个返回值。但是我怎样才能用正确的语法写出来:

    private Task<bool> CreateTask() {
        return new Task<bool>(
            async () =>  await DoSomething().ConfigureAwait(false));
    }

我收到消息,异步 lambda 表达式无法转换为 func。 所以我的问题是:它是如何正确编写的?

【问题讨论】:

  • 这两种方法都是错误的。 DoSomething() 已经返回了一个正在运行的任务,所以你可以按原样返回它,return (Task)DoSomething();await 等待 已经运行的任务完成,它不会使其异步启动。没有理由使用new 创建冷任务。在第二种情况下,应该是什么值?
  • 这听起来像是XY Problem 的情况。你对 X 有问题,认为 Y 是解决方案,当它不起作用时询问 Y。您要解决的实际问题是什么?
  • 要处理异常,请使用异常处理程序将您的await 调用附上,就像使用同步方法一样。 await 将导致抛出原始异常。你可以写例如try{ .... await CallMyServerAsync();}catch(WebException exc){...},就像你写try{ .... await CallMyServer();}catch(WebException exc){...},如果CallMyServer是一个阻塞方法

标签: c# asynchronous async-await task


【解决方案1】:

我现在想创建一些异步任务而不启动它们。

对于您要解决的任何问题,这都是错误的解决方案。如果您想定义将来要运行的代码,那么您应该使用委托:

private Func<Task> CreateTaskFactory()
{
  return async () => await DoSomething().ConfigureAwait(false);
}

但是为了处理异常,我在函数中添加了一个返回值。

同样,这不是最好的解决方案。任务已经很好地理解了异常,无需编写任何额外的代码。

如果你确实需要返回一个值(作为数据),那么你可以返回一个创建Task&lt;T&gt;的委托:

private Func<Task<int>> CreateTaskFactory()
{
  return async () => await DoSomethingReturningInt().ConfigureAwait(false);
}

【讨论】:

  • CreateTaskFactory 可以只是 return DoSomething(); async 代表在这里没有任何优势。
  • @Servy:我假设 op 现在想定义操作,但稍后再启动。
  • 对不起,我的意思是return () =&gt; DoSomething();
  • @Servy:哦,是的。绝对可以,除非操作的代表不是微不足道的。
  • 当然,但如果它足够重要,最好将其重构为命名方法。
猜你喜欢
  • 2015-10-30
  • 2021-04-06
  • 1970-01-01
  • 1970-01-01
  • 2015-08-21
  • 2011-12-08
  • 2015-07-04
  • 1970-01-01
  • 2013-04-02
相关资源
最近更新 更多