运行时任务被取消,我的程序无法继续运行
Task is cancelled when it is running,My program can't go on running
CancellationTokenSource cts = new CancellationTokenSource();
List<Task> allTask = new List<Task>();
for (int i = 0; i < 10000; i++)
{
int j = i;
allTask.Add(Task.Factory.StartNew(() =>
{
if (cts.Token.IsCancellationRequested)
{
return;
}
cts.Cancel();
Thread.Sleep(1000);
Console.WriteLine("I'm doing it");
}, cts.Token, TaskCreationOptions.LongRunning, TaskScheduler.Current));
}
Task.WaitAll(allTask.ToArray());
Console.WriteLine("Implementation success!");
Console.ReadKey();
关于问题,取消任务后,我的程序没有继续运行。这是为什么?我明确取消了。
为什么我的程序没有输出"Implementation success"
?
这是设计使然;调用 cts.Cancel()
将始终在 WaitAll
调用上抛出 TaskCanceledException
。因此,您的代码将 1000 个任务排入队列,等待所有任务,抛出异常,然后您的程序终止。
查看 TPL 文档 https://docs.microsoft.com/en-us/dotnet/standard/parallel-programming/how-to-cancel-a-task-and-its-children#example 明确告诉您如何使用 AggregateException
处理程序检查 InnerExceptions
.[=19 中的 TaskCancelledException
来处理这种情况=]
如果您希望您的代码到达 "Implementation Success" w/正确处理取消,请添加一个 AggregateException
处理程序:
CancellationTokenSource cts = new CancellationTokenSource();
List<Task> allTask = new List<Task>();
for (int i = 0; i < 10000; i++)
{
int j = i;
allTask.Add(Task.Factory.StartNew(() =>
{
if (cts.Token.IsCancellationRequested)
{
return;
}
cts.Cancel();
Thread.Sleep(1000);
Console.WriteLine("I'm doing it");
}, cts.Token, TaskCreationOptions.LongRunning, TaskScheduler.Current));
}
try
{
Task.WaitAll(allTask.ToArray());
}
catch (AggregateException ex)
{
//handle the cancelled tasks here, though you are doing it on purpose...
Console.WriteLine("One or more tasks were cancelled.");
}
Console.WriteLine("Implementation success!");
Console.ReadKey();
我有类似的问题,我的任务工作时间太长,解决方法如下:
在 class xxx 我有私人 collection :
private List<TaskWork> _taskCollection = new List<TaskWork>();
向列表添加新任务:
var cancellationToken = new CancellationTokenSource();
cancellationToken.CancelAfter(10000);
var taskWork = new TaskWorkVM
{
CancellationToken = cancellationToken.Token,
StartTime = DateTime.Now
};
taskWork.Task = Task.Run(() => { [some_work]; }, taskWork.CancellationToken);
_taskCollection.Add(taskWork);
检查是否完成了某些任务,并从 collection 中删除:
var completedTask = _taskCollection.Where(t => t.Task.IsCompleted).FirstOrDefault();
if (completedTask != null)
{
_taskCollection.Remove(completedTask);
}
你可以做while来检查列表,我觉得简单的while就够了:
while (_taskCollection.Count() > 0)
{
//do something
}
任务 class 有其他标志 IsCanceled 或者您可以使用任务状态。
CancellationTokenSource cts = new CancellationTokenSource();
List<Task> allTask = new List<Task>();
for (int i = 0; i < 10000; i++)
{
int j = i;
allTask.Add(Task.Factory.StartNew(() =>
{
if (cts.Token.IsCancellationRequested)
{
return;
}
cts.Cancel();
Thread.Sleep(1000);
Console.WriteLine("I'm doing it");
}, cts.Token, TaskCreationOptions.LongRunning, TaskScheduler.Current));
}
Task.WaitAll(allTask.ToArray());
Console.WriteLine("Implementation success!");
Console.ReadKey();
关于问题,取消任务后,我的程序没有继续运行。这是为什么?我明确取消了。
为什么我的程序没有输出"Implementation success"
?
这是设计使然;调用 cts.Cancel()
将始终在 WaitAll
调用上抛出 TaskCanceledException
。因此,您的代码将 1000 个任务排入队列,等待所有任务,抛出异常,然后您的程序终止。
查看 TPL 文档 https://docs.microsoft.com/en-us/dotnet/standard/parallel-programming/how-to-cancel-a-task-and-its-children#example 明确告诉您如何使用 AggregateException
处理程序检查 InnerExceptions
.[=19 中的 TaskCancelledException
来处理这种情况=]
如果您希望您的代码到达 "Implementation Success" w/正确处理取消,请添加一个 AggregateException
处理程序:
CancellationTokenSource cts = new CancellationTokenSource();
List<Task> allTask = new List<Task>();
for (int i = 0; i < 10000; i++)
{
int j = i;
allTask.Add(Task.Factory.StartNew(() =>
{
if (cts.Token.IsCancellationRequested)
{
return;
}
cts.Cancel();
Thread.Sleep(1000);
Console.WriteLine("I'm doing it");
}, cts.Token, TaskCreationOptions.LongRunning, TaskScheduler.Current));
}
try
{
Task.WaitAll(allTask.ToArray());
}
catch (AggregateException ex)
{
//handle the cancelled tasks here, though you are doing it on purpose...
Console.WriteLine("One or more tasks were cancelled.");
}
Console.WriteLine("Implementation success!");
Console.ReadKey();
我有类似的问题,我的任务工作时间太长,解决方法如下: 在 class xxx 我有私人 collection :
private List<TaskWork> _taskCollection = new List<TaskWork>();
向列表添加新任务:
var cancellationToken = new CancellationTokenSource();
cancellationToken.CancelAfter(10000);
var taskWork = new TaskWorkVM
{
CancellationToken = cancellationToken.Token,
StartTime = DateTime.Now
};
taskWork.Task = Task.Run(() => { [some_work]; }, taskWork.CancellationToken);
_taskCollection.Add(taskWork);
检查是否完成了某些任务,并从 collection 中删除:
var completedTask = _taskCollection.Where(t => t.Task.IsCompleted).FirstOrDefault();
if (completedTask != null)
{
_taskCollection.Remove(completedTask);
}
你可以做while来检查列表,我觉得简单的while就够了:
while (_taskCollection.Count() > 0)
{
//do something
}
任务 class 有其他标志 IsCanceled 或者您可以使用任务状态。