2017-09-08 65 views
0

在我的MVC網站上有用於處理數據的顯示按鈕。這個按鈕調用ActionResult方法「ProcessData」。如何取消當前從另一個ActionResult方法運行的ActionResult方法?

public ActionResult ProcessData() 
    { 
     bool isComplete = false; 
     string errMessage = ""; 
     try 
     { 
      //Calculate something that take long time. 


      isComplete = true; 
     } 
     catch (Exception e) 
     { 
      errMessage = e.Message; 
     } 


     return Json(new { IsComplete = isComplete, ErrorMessage = errMessage }); 
    } 

而第二個按鈕用於取消處理。這個按鈕調用ActionResult方法「CancelProcessData」。

public ActionResult CancelProcessData() 
    { 
     bool isCancelComplete = false; 
     string errMessage = ""; 
     try 
     { 
      //Cancel Process Data 


      isCancelComplete = true; 
     } 
     catch (Exception e) 
     { 
      errMessage = e.Message; 
     } 


     return Json(new { IsCancelComplete = isCancelComplete , ErrorMessage = errMessage }); 
    } 
  1. 當用戶點擊在過程按鈕,數據是處理和需要較長的時間。
  2. 我希望用戶能夠通過點擊取消按鈕來取消進程。

如何取消當前正從另一個ActionResult方法運行的ActionResult方法?請介紹我。

P.S.對不起,英語不好。

編輯1:這是代碼ProcessData.cshtml

<script> 
    function ProcessData() { 
     var actionUrl = '@Url.Action("ProcessData", "Home")'; 
     $.ajax({ 
      type: "POST", 
      url: actionUrl, 
      contentType: "application/Json", 
      success: function (result) { 
       if (result.IsComplete) { 
        var reUrl = '@Url.Action("Index", "Home")'; 
        window.location = reUrl; 
       } 
      }, 
      error: function() { 
       alert("Error"); 
      } 
     }); 
    } 

    function CancelProcessData() { 
     var actionUrl = '@Url.Action("CancelProcessData", "Home")'; 
     $.ajax({ 
      type: "POST", 
      url: actionUrl, 
      contentType: "application/Json", 
      success: function (result) { 
       if (result.IsComplete) { 
        alert("Cancel Complete"); 
       } 
      }, 
      error: function() { 
       alert("Error"); 
      } 
     }); 
    } 
</script> 

<button onclick="ProcessData();">Process Data</button> 
<button onclick="CancelProcessData();">Cancel Process Data</button> 

編輯完1

編輯2:當我搜索很長一段時間。我找到了取消過程的解決方案。這個代碼顯示

public async System.Threading.Tasks.Task<ActionResult> ProcessData() 
    { 
     bool isComplete = false; 
     bool isCancel = false; 
     string errMessage = ""; 
     try 
     { 
      await System.Threading.Tasks.Task.Run(() => { 
       for (int i = 0;i< Int32.MaxValue; i++) 
       { 
        if (HttpContext.Response.ClientDisconnectedToken.IsCancellationRequested) 
        { 
         isCancel = true; 
         break; 
        } 
       } 
      }); 

      isComplete = true; 
     } 
     catch (Exception e) 
     { 
      errMessage = e.Message; 
     } 


     return Json(new { IsComplete = isComplete, ErrorMessage = errMessage, IsCancel = isCancel }); 
    } 

下面這個腳本函數

<script> 
    var ajaxProcessDatarequest; 
    function ProcessData() { 
     var actionUrl = '@Url.Action("ProcessData", "Home")'; 
     ajaxProcessDatarequest = $.ajax({ 
      type: "POST", 
      url: actionUrl, 
      contentType: "application/Json", 
      success: function (result) { 
       if (result.IsComplete) { 
        if (!result.IsCancel) { 
         var reUrl = '@Url.Action("Index", "Home")'; 
         window.location = reUrl; 
        } 
       } 
      }, 
      error: function() { 
       alert("Error"); 
      } 
     }); 
    } 

    function CancelProcessData() { 
     ajaxProcessDatarequest.abort(); 
    } 
</script> 

編輯完2

+0

你可以張貼的取消,顯示按鈕的HTML部分。你打電話使用阿賈克斯? – praga2050

+0

你不能(它們是2個單獨的請求) –

+0

'ProcessData'和'CancelProcessData'帶有不同的請求(它們都被聲明爲'ActionResult'),似乎你不能從另一個方法請求中取消HTTP請求,如果第一個請求已經開始。 –

回答

0

(現在,我不知道如果一個Session值保持相同的通過出Http請求或獲取更新)

這取決於您正在運行的是哪種進程。它不會停止正在運行的進程,但它可以撤銷並停止進一步的處理。

在你的javascript中創建一個名爲processTimeStamp的變量。注意,它的聲明必須在這兩個函數之外。在調用過程數據之前,分配processTimeStamp,這將是ProcessDataCancelProcessData方法的參數。因爲變量在全局範圍內,所以這兩個方法都會發送相同的值。

<script> 
    var processTimeStamp; 
    function ProcessData() { 
     var actionUrl = '@Url.Action("ProcessData", "Home")'; 
     processTimeStamp = new Date().getTime().toString(); 

     $.ajax({ 
      type: "POST", 
      url: actionUrl, 
      data: { 
       processTimeStamp: processTimeStamp 
      }, 
      contentType: "application/Json", 
      success: function (result) { 
       if (result.IsComplete) { 
        var reUrl = '@Url.Action("Index", "Home")'; 
        window.location = reUrl; 
       } else if (result.IsCancelComplete) { 
        alert("process was cancelled"); 
       } 
      }, 
      error: function() { 
       alert("Error"); 
      } 
     }); 
    } 

    function CancelProcessData() { 
     var actionUrl = '@Url.Action("CancelProcessData", "Home")'; 
     $.ajax({ 
      type: "POST", 
      url: actionUrl, 
      data: { 
       processTimeStamp: processTimeStamp 
      }, 
      contentType: "application/Json", 
      success: function (result) { 
      }, 
      error: function() { 
       alert("Error"); 
      } 
     }); 
    } 
</script> 

控制器

在你CancelProcessData方法的processTimeStamp值分配給Session["CancelProcessTimestamp"]。你根本無法知道這個過程是否被取消。

在您的ProcessData方法中,檢查processTimeStamp是否通過,與每個進程之前的Session["CancelProcessTimestamp"]相同。我的意思是你沒有任何選擇。(有點像你會如何處理任務並行庫CancellationToken

public ActionResult ProcessData(string processTimeStamp) 
{ 
    bool isComplete = false; 
    bool isCancelComplete = false; 
    string errMessage = ""; 

    try 
    { 

     // process 1 <-- this starts immediately. So you can't stop that. 

     if(Convert.ToString(Session["CancelProcessTimestamp"]) != processTimeStamp) 
     { 
      // process 2 
     } 
     else 
     { 
      isCancelComplete = true; 
     } 

     // OTHER PROCESSES 

     if(Convert.ToString(Session["CancelProcessTimestamp"]) != processTimeStamp) 
     { 
      // update to database 
      isComplete = true; // only if it completes the last process 
     } 
     else 
     { 
      // you can undo the work done in process 1, 2 etc. 
      // Like deleting an uploaded file. Or if any primary key is returned from Process 1, then delete the corresponding entry in Data base 
      isCancelComplete = true; 
     } 
    } 
    catch (Exception e) 
    { 
     errMessage = e.Message; 
    } 

    return Json(new { IsComplete = isComplete, IsCancelComplete = isCancelComplete , ErrorMessage = errMessage }); 
} 


public ActionResult CancelProcessData(string processTimeStamp) 
{ 
    Session["CancelProcessTimestamp"] = processTimeStamp; 
    return Json(true); 
} 
+0

我可以在我的Edit 2.please中找到解決方案。非常感謝你。 – user2955394

+0

@ user2955394它工作嗎?在你的編輯中,過程在哪裏? – adiga

+0

請在我的問題中看到我在Edit2中使用long for循環的測試過程。當點擊進程按鈕時,請求調用方法ProcessData並長時間運行。但是當點擊取消按鈕時,它會調用abort()。當ajax調用abort()時,HttpContext.Response.ClientDisconnectedToken.IsCancellationRequested被設置爲true,然後我打破循環。這對我有用。 – user2955394

相關問題