据我了解, ( 和 ) 中的所有三个静态方法都在后台Parallel
创建任务。For
ForEach
Invoke
您可以通过取消内部的令牌来停止创建这些任务ParallelOptions
。
我做了两个简单的例子。
在第一个中使用For
第二个中的方法Invoke
。
在该For
方法的情况下,行为是预期的,在取消令牌后,新任务的创建将停止。在该Invoke
方法的情况下,这不会发生。无论我在 Invoke 方法中放了多少方法,它们总是在令牌取消后执行。我不明白为什么会这样。
在docs.microsoft.com 的Parallel.Invoke
方法中
有人说:
与结构一起传递的取消令牌
ParallelOptions
使调用者能够取消整个操作。
问题:为什么在 Invoke 方法的情况下,所有任务都已执行,而取消令牌则无济于事?或者也许我做错了什么,然后告诉我什么。
using System;
using System.Threading;
using System.Threading.Tasks;
namespace ConsoleApp1
{
class MyClass
{
public int a = 0;
public void Add()
{
lock (this)
{
Thread.Sleep(100);
Console.WriteLine($"Do Add {DateTime.Now}, a={a}");
a++;
}
}
}
class Program
{
static void Main(string[] args)
{
void MyMethodForCancel(CancellationTokenSource cancellationTokenSource)
{
Random random = new Random();
while (true)
{
if (random.Next(1, 100) == 50)
{
cancellationTokenSource.Cancel();
Console.WriteLine($"Cancel token {DateTime.Now}");
return;
}
}
}
CancellationTokenSource cancellationTokenSource = new CancellationTokenSource();
ParallelOptions parallelOptions = new ParallelOptions();
parallelOptions.CancellationToken = cancellationTokenSource.Token;
MyClass myClass2 = new MyClass();
Action[] actions = new Action[50];
for (int i = 0; i < actions.Length; i++)
{
actions[i] = myClass2.Add;
}
Task MyTask1 = Task.Run(() => Parallel.Invoke(parallelOptions, actions));
Task MyTask2 = Task.Run(() => { Thread.Sleep(1); MyMethodForCancel(cancellationTokenSource); });
try
{
Task.WaitAll(MyTask1, MyTask2);
}
catch
{
}
Console.WriteLine($"a = {myClass2.a}"); //a = 50. Always.
}
}
}