2017-09-27 16 views
0

私の見解では、Start()アクションを呼び出すボタンとStop()を呼び出すボタンの2つのボタンがあります。コントローラは次のようになります。MVCで非同期アクションをキャンセルできません

public class TestController : AsyncController 
{ 
    public static CancellationTokenSource cts = new CancellationTokenSource(); 

    public void StartAsync() 
    { 
     cts = new CancellationTokenSource(); 
     CancellationToken cancellationToken = cts.Token; 
     AsyncManager.OutstandingOperations.Increment(); 

     AsyncManager.Parameters["task"] = Task.Factory.StartNew(() => 
     { 
      try 
      { 
       while() { 
        if (cancellationToken.IsCancellationRequested) 
         break; 

        // Do stuff 
       } 
      } 
      finally 
      { 
       AsyncManager.OutstandingOperations.Decrement(); 
      } 
     }, cancellationToken); 
    } 

    public ActionResult StartCompleted(Task task) 
    { 
     try 
     { 
      task.Wait(); 
      return Json(new { success = true }, JsonRequestBehavior.AllowGet); 
     } 
     catch (Exception e) 
     { 
      return Json(new { success = false }, JsonRequestBehavior.AllowGet); 
     } 
    } 

    public void StopAsync() 
    { 
     cts.Cancel(); 
    } 

    public ActionResult StopCompleted() 
    { 
     return Json(new { success = true }, JsonRequestBehavior.AllowGet); 
    } 
} 

しかし、私が停止ボタンをクリックしたとき、停止アクションは開始終了後にのみ呼び出されます。どのように私はアクションを停止するはずですか?ブックProの.NETパフォーマンスから

答えて

0

私は私のコントローラは、非同期要求を処理できるようにするために

[SessionState(SessionStateBehavior.ReadOnly)] 

を使用する必要がありました。 MVC 2を使用していて、その属性が利用できないため、カスタムルートハンドラを作成する必要がありました。 Disable Session state per-request in ASP.Net MVC

+0

IIS Expressの問題になりました:https://github.com/aspnet/Mvc/issues/5239#issuecomment-323567394 –

2

引用:既に作業を実行する

キャンセルは、その作業を実行するコードからの協力が必要です。しかし、まだ実行を開始していないタスクは、悪影響を受けることなく完全に取り消すことができます。

これは、ラムダ自体で、作業がキャンセルされているかどうかを確認し、それに応じて動作する必要があることを意味します。例:

if (cts.IsCancellationRequested) return; 

キャンセルリクエストを確認していますか?

更新

チェックが// Do stuff部分のどこかにする必要があります。たとえば、何百ものアイテムをループして、何らかの処理を行い、最後に何らかの結果を返さなければならないタスクとして複雑な複数部分計算を実行している場合、ループの各繰り返しの開始時にキャンセルを確認することができます。

他の例では、タスク内にキャンセルをサポートするAPI(HttpClient.GetAsyncなど)を使用している場合は、そのAPIの適切なオーバーロードにCancellationTokenを渡す必要があります。

+0

この 'if'文が' // Do stuff'コメントでコードブロック内にある必要があることを明示的に述べる価値があります。 – Enigmativity

+0

私はキャンセル要求を確認しており、それを反映するようにコードを更新しました。しかし、ここでの主な問題は、ストップが決して呼び出されないことです。 –

関連する問題