如何暂停和恢复异步运行的任务

时间:2016-04-05 07:09:53

标签: .net c#-4.0 asynchronous async-await

我有一个长时间运行的代码,我想要暂停恢复功能。在start方法中,我正在编写代码并启动新的异步任务。但我希望按需暂停/恢复此任务。

  var myTask;
  public void start()
    {
        myTask = Task.Factory.StartNew(() =>
        {
         ///my business logic
        });
    }

2 个答案:

答案 0 :(得分:3)

您必须了解任务和线程之间的差异。任务是你想要完成的事情。线程是执行该任务的许多可能的工作者之一。单独的任务不必由单独的线程执行。相同的线程可以执行多个任务。一个任务可能由多个线程执行。

如果你想要一个控制级别,你希望能够在任何时刻暂停一个正在运行的任务,无论它现在做什么,考虑使用一个线程。请注意,暂停线程一段时间后,它将保留当时可能使用的稀缺资源。

因此,仅将您的流程保留在某些预定义的执行点可能更为明智。在这种情况下,任务可能是更明智的选择。

通过使用任务,您表示您不希望被执行者所困扰,因此您无法控制执行者。事实上,通过使用任务,您表达甚至不关心整个过程是由一个线程还是多个线程处理。

如果要在流程中的某些已定义点停止执行流程,请考虑将任务划分为子任务,每个子任务在您希望流程停止的位置结束。通过使用Task.ContinueWith,您可以决定任务何时应该继续处理该过程的下一步。

简洁的解决方案是将您的进程(或任务)包装到类中用户可以说的类中:运行直到执行步骤X,或者:运行直到达到状态Y.这样,类的用户甚至不必知道您的进程是使用Task还是Thread运行。

答案 1 :(得分:2)

好吧,您可以创建自己的简单任务调度程序,并从任务内部重复检查当前任务状态。为了使线程安全,我们需要将bool标记标记为volatile

class MySimpleTaskScheduler
{
   private volatile bool isPaused;
   private volatile bool isStopped;
   private Task _myBackgroundTask;

   public void StartTask()
   {
       _myBackgroundTask = new Task.Run(() => 
       {
          while(!isStopped)
          {
             while(!isPaused && !isStopped)
             {
                .. do something
                Thread.Sleep(100);  // set some delay before check if task is set on pause
             }

             Thread.Sleep(100);  // set some timeout before check if task is stopped              }
       });
   }

   public void Pause()
   {
      isPaused = true;     
   }

   public void Resume()
   {
      isPaused = false;         
   }

   public void Stop()
   {
      isPaused = true;       
      isStopped = true;       
   }
} 
相关问题