【问题标题】:Predefined task return async many times预定义任务多次异步返回
【发布时间】:2018-12-17 21:58:17
【问题描述】:

我在班级顶部定义了一个任务,如下所示:

Task<string> MainTask {get;set;}

然后我在应用程序内部构建这个任务。

MainTask = new Task<string>( () => 
{
    return Task.Run<string>( async () => 
    {
        await GetResult();

    }).Result;
});

我想循环,直到任务返回数据,但是一旦任务第一次完成,我就无法再次启动它。

bool gotResult = false;
While(gotResult == false)
{
  MainTask.Start();
  MainTask.Wait();
  if(MainTask.Result)
  {
    gotResult = true;
  }
}

【问题讨论】:

  • 这段代码很奇怪。你能解释一下为什么你不只是在循环中做一个await GetResult();吗?你为什么要做这种将 lambda 包装在一个任务中的业务,而该任务本身又包装在一个任务中的 lambda 中?这似乎是很多不必要且危险的错误间接。
  • 你为什么使用你的Task作为你的类的一个字段而不是等待和异步你的async方法?
  • hm...你不应该等待 GetResultAsync() 吗??

标签: c# multithreading task


【解决方案1】:

MainTask 不应该是 Task,它应该是 Func&lt;Task&gt;(或者,在这种情况下,由于异步操作似乎提供了一个布尔值,一个 Func&lt;Task&lt;bool&gt;&gt;,允许您启动异步只需调用该方法即可随时进行操作。

所以定义为:

Func<Task<bool>> AsyncOperation {get;set;}

将其用作:

while(!await AsyncOperation())
{
    //do nothing
}

至于分配,您只需分配您拥有的异步方法即可:

AsyncOperation = GetResult;

请注意,您真的不应该每次都使用Task 构造函数。不要处理未开始的任务,它只会引起混乱。也不需要使用Task.Run 来调用异步方法。它已经是异步的了。也不需要使用 async lambda 来调用异步方法,这两件事都只是增加了开销,并没有增加任何价值。

【讨论】:

    猜你喜欢
    • 2013-04-16
    • 2018-09-03
    • 2015-01-12
    • 2014-10-01
    • 2016-08-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多