2016-04-05 18 views
1

私は長い実行コードを持っています。開始メソッドで私のコードを書いて、新しい非同期タスクを開始します。しかし、私はこの仕事を一時停止/再開したいと思っています。非同期に実行されるタスクの一時停止と再開方法

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

はループか何かをやってあなたのコードですか? –

+3

タスクスケジューリングは協調的です。タスクを一時停止するには、これを伝える手段を使用する必要があります。例えば、センチネル旗を設定することによって実行することができる。しかし、旗を守り尊重することは任務に任されます。プリエンプティブスケジューリング(強制的に一時停止することができます)を希望する場合は、スレッドに戻す必要があります。ネイティブコールを実行しているときでも、スレッドを一時停止することはできません。 – Douglas

+1

ベストから学ぶ。ここでStephen Toubさんが問題に取り組んでいます:http://blogs.msdn.com/b/pfxteam/archive/2013/01/13/cooperatively-pausing-async-methods.aspx –

答えて

3

タスクとスレッドの違いに注意する必要があります。仕事はあなたがしたいものです。スレッドは、そのタスクを実行する多くの可能なワーカーの1つです。独立したスレッドで別々のタスクを実行する必要はありません。同じスレッドが複数のタスクを実行できます。 1つのタスクは複数のスレッドで実行される可能性があります。

現在実行中のタスクに関係なく、いつでも実行中のタスクを一時停止できるようにするレベルの制御が必要な場合は、スレッドの使用を検討してください。スレッドをしばらく停止すると、その時点で使用する可能性のある不十分なリソースが保持されることに注意してください。

したがって、あらかじめ定義された特定の実行ポイントでプロセスを保持するほうが賢明かもしれません。その場合、タスクは賢明な選択かもしれません。

タスクを使用することで、誰が実行しているかに気にしたくないと表現するので、実行者を制御することはできません。実際には、タスクを使用することによって、完全なプロセスが1つのスレッドまたは複数のスレッドによって処理されるかどうかは気にしないことを表現します。

プロセス内の特定の定義されたポイントでプロセスの実行を停止する場合は、タスクをサブタスクに分割することを検討してください。各サブタスクは、プロセスを停止させたい時点で終了します。 Task.ContinueWithを使用すると、タスクがプロセスの次のステップを処理し続けるタイミングを決めることができます。

クラスのユーザーがステップXが実行されるまで実行するか、または:状態Yに達するまで実行すると言うことができるクラスに、プロセス(またはタスク)をラップすることです。このように、クラスのユーザーは、プロセスがタスクまたはスレッドを使用して実行されているかどうかを知る必要さえありません。

+0

「実行中のタスクをしばらく停止する」ことができるスレッドAPIの例を提供できますか? –

+0

@KirillShlenskiy ['System.Threading.Thread.Suspend()'](https://msdn.microsoft.com/en-us/library/system.threading.thread.suspend(v = vs.110)。 aspx)、そのメソッドは廃止とマークされており、セマフォ、ミューテックス、または他のロジックを使用して実行を一時停止できる「チェックポイント」を入れるという別の方法を使用することを本当にお勧めします。 –

+0

私はかなり同意します。いつでも。スレッドが何をしているのか分からないので、サスペンドが何をすることができるのか分からない。それ以外に、すぐに他の仕事を止めることが本当に必要かどうか疑問に思う。 –

0

あなた自身のシンプルなタスクスケジューラを作成し、タスクの内部から現在のタスクステータスを繰り返し確認することができます。それは我々が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;  
    } 
} 
関連する問題