【发布时间】:2020-11-24 12:54:22
【问题描述】:
如何在后台运行此任务并且我的其他 Web 内容(服务器 API)应该可以工作?也可以在任何时候取消。因为我的服务器能够运行繁重的操作和多线程。
C#
[HttpPost]
[AsyncTimeout(30 * 60 * 1000)]
//ConnectionId show importing data on UI as progress bar using SignalRProgress.
//Path import file path for import some bulk data in background.
//cancellationToken to cancel task when user need.
public async Task<ActionResult> LongRunningTask(string ConnectionId, string Path, System.Threading.CancellationToken cancellationToken)
{
CancellationToken disconnectedToken = Response.ClientDisconnectedToken;
var source = CancellationTokenSource.CreateLinkedTokenSource(cancellationToken, disconnectedToken);
string someResponse = "Empty";
await Task.Run(() =>
{
foreach (var item in spec)
{
i++;
try
{
if (source != null && source.IsCancellationRequested)
{
//abort or cancel this thread and
//custome method that add progress to an hub context
//update UI for task cancelation with how much importing is done
Utility.SignalRProgressEvent.SendProgress(ConnectionId, Message, DonePercentage);
break;
}
importedDetails = service.ImportData(item, source.Token);
}
catch (CustomException ex)
{
someResponse += what is the validation issue in which record;
}
catch (JsonSerializationException ex)
{
someResponse += which attribute have serialization error;
}
catch (Exception ex)
{
throw ex;
}
//update UI for how much import is done
someResponse += information of errors/importedid/validaiton issue;
Utility.SignalRProgressEvent.SendProgress(ConnectionId, Message, DonePercentage);
}
}, source.Token);
return Json(someResponse, JsonRequestBehavior.AllowGet);
}
Javascript
/*Update progress bar*/
function ProgressBarModal(showHide) {
if (showHide === 'show') {
$('#mod-progress').modal('show');
if (arguments.length >= 2) {
var percentage = "0";
if (arguments.length >= 3) {
percentage = arguments[2]
$('#ProgressMessage').width(percentage);
if (percentage == "100%") {
ProgressBarModal();
}
}
$('#progressBarTextMessage').text(arguments[1] + " " + percentage);
window.progressBarActive = true;
}
} else {
$('#mod-progress').modal('hide');
window.progressBarActive = false;
}
}
var xhr = undefined;
/*start import*/
function StartImport() {
xhr = $.ajax({
type: 'POST',
url: "@Url.Action("Import", "BulkOps")",
data: data,
async: true, //I want run progress bar using JS
beforeSend: function () {
ProgressBarModal('show');
},
success: function (data) {
//import done
},
error: function (err) {
//handle import failing
},
complete: function (data) {
//share import report if possible
}
});
});
/*Abort running import*/
function AbortImport() {
xhr.abort("Task aborted by the user.");
});
是否有任何可能的解决方案来中止相同的任务?但服务器不应停留在同一个长时间运行的进程上。
提前致谢。
请忽略我过去的问题。我放弃了线程的想法。
我正在尝试取消我在进程之间的长时间运行的任务,这 当我们使用单线程时是可能的,但我想运行任何 在后台线程中长时间运行,因此我可以在我的 网络。
这是否可以取消或中止正在运行的线程 背景?
[HttpPost] [AsyncTimeout(30 * 60 * 1000)] //ConnectionId show importing data on UI as progress bar using SignalRProgress. //Path import file path for import some bulk data in background. //cancellationToken to cancel task when user need. public ActionResult LongRunningTask(string ConnectionId, string Path, System.Threading.CancellationToken cancellationToken) { CancellationToken disconnectedToken = Response.ClientDisconnectedToken; var source = CancellationTokenSource.CreateLinkedTokenSource(cancellationToken, disconnectedToken); string someResponse = "Empty"; Thread t = new Thread(() => { if (source != null && source.IsCancellationRequested || string.IsNullOrWhiteSpace(ConnectionId)) { //abort or cancel this thread and //custome method that add progress to an hub context //update UI for task cancelation with how much importing is done Utility.SignalRProgressEvent.SendProgress(ConnectionId, Message, DonePercentage); } //update UI for how much import is done someResponse += information of errors/importedid/validaiton issue; Utility.SignalRProgressEvent.SendProgress(ConnectionId, Message, DonePercentage); }); t.Start(); //How do i wait here with main thread until above thread complete. return Json(someResponse, JsonRequestBehavior.AllowGet); }附: 1 用任务更改上面的线程然后我的完整服务器卡住了 直到任务完成。
附: 2 将上面的线程设为后台,然后主线程将启动 该线程并完成此 ajax 调用。然后我无法取消 任务。
我需要一个解决方案,允许我运行从网络导入 进度条,应该可以在任何时候取消,也可以在任何其他 mvc 上取消 动作应该不会受到这个动作的太大影响。因为我的服务器是 能够运行繁重的操作和多线程。
【问题讨论】:
-
你为什么用
Thread而不是Task? -
看看这个:What's wrong with using Thread.Abort。最重要的是,.NET Core 不支持此方法。
-
@PeterCsala 我试图在线程中运行我的导入,因为我想在导入期间运行我的服务器 api 和其他服务器任务。
-
@TheodorZoulias,不需要使用线程,我只是想通过后台导入实现取消。
-
请不要改变问题的主要焦点。编辑应仅限于澄清和改进。如果您还有其他问题,请发布另一个问题。
标签: c# asp.net-mvc multithreading cancellation-token background-thread