如何在后台运行非必要的计算?

时间:2015-05-04 15:24:23

标签: c# concurrency task-parallel-library .net-4.5

这个问题是Why is this code running synchronously?的后续问题。我意识到我的真​​实问题比那篇文章中的问题更高。我现在要问的问题是“我该如何做到这一点?”

我想在C#中使用并发来计算后台的东西。我有类ptsTin,它代表现有的地面。我想尽快加载。有些工作是必不可少的,因为在工作完成之前你没有实例。例如,在.LoadPoints()和.LoadTriangles都完成之前,没有ptsTin实例。

工作的其他部分不是必需的,可以在以后计算,即使以后是0.2秒。我想在一个新的线程中开始非必要的工作而忘记它。如果它正在处理的值尚未就绪,则该值将为空。

所以这就是我想做的事情。代码现在在控制台应用程序中,但有一天将在GUI应用程序中。注意,这是伪代码。我知道它不会像这样工作,它的目的是传达我想知道如何做的事情:

  static void Main(string[] args)
  {
      var myTin = ptsDTM.Load("SomeFile.ptsTin");
      // Do other stuff here like getElevationAtAPoint();
  }

  public static ptsTin Load(String file)
  {
     // Essential Work
     ptsTin newTin = new ptsTin();
     newTin.LoadPoints(file);
     newTin.LoadTriangles(file);

     // At this point I could return, but I want other stuff done
     // Non-essential work -- I want this on a "background" task
     newTin.BoundingBox = newTin.ComputeBBInTheBackground();    

     // Now return without waiting for ComputeBB to finish
     return newTin;
  }

如果另一个方法稍后要求tin.BoundingBox,但该值还没有准备好,它仍然是null。其他方法将知道该值在非空时有效。

我如何做到这一点?

我不知道答案是否使用async和await,Task.Run或任何其他方法。

1 个答案:

答案 0 :(得分:2)

  

我如何做到这一点?

您可以将BoundingBox更改为将来完成的Task<BoundingBox>来完成此操作。

public static ptsTin Load(String file)
{
    // Essential Work
    ptsTin newTin = new ptsTin();
    newTin.LoadPoints(file);
    newTin.LoadTriangles(file);

    // At this point I could return, but I want other stuff done
    // Non-essential work -- I want this on a "background" task
    newTin.BoundingBox = Task.Run(() => newTin.ComputeBB());

    // Now return without waiting for ComputeBB to finish
    return newTin;
}

现在,您可以在其他方法中查找状态:

if (ptsTin.BoundingBox.Status == TaskStatus.Completed)
{
     // Finished computing
}