在我的MVC网站上有显示流程数据的按钮。此按钮调用ActionResult方法“ProcessData”。
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 });
}
如何取消当前从另一个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 :(得分:0)
(现在,我不确定会话值是否在Http请求中保持不变或更新)
这取决于您正在运行的流程类型。它不会停止任何正在运行的进程,但它可以撤消并停止进一步处理。
在您的javascript中创建一个名为processTimeStamp
的变量。注意,它的声明必须在这两个函数之外。在调用流程数据之前,请分配processTimeStamp
,这将是ProcessData
和CancelProcessData
方法的参数。由于变量在全局范围内,因此将向这两种方法发送相同的值。
<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);
}