Пожалуйста, если кто-нибудь может мне помочь. Я пытаюсь использовать токены отмены, связанные с TPL. Проблема заключается в том, что после отмены основного CancellationTokenSource значение свойства IsCancellationRequested связанного токена по-прежнему равно «false».
Я начинаю две задачи, на всякий случай - но это должно быть одно и то же. Первому передаю CancellationToken, а второму - CancellationTokenSource. Поведение такое же: в циклах while - условие connectedToken.IsCancellationRequested остается «ложным» после отмены.
Вот код, который я использую:
public class Manager
{
private Task tokenTask;
private Task sourceTask;
private CancellationTokenSource mainCancelationTokenSource;
private CancellationToken mainToken;
public Manager()
{
this.mainCancelationTokenSource = new CancellationTokenSource();
this.mainToken = mainCancelationTokenSource.Token;
this.mainToken.Register(MainCanceled);
}
public void Start()
{
Workers w = new Workers();
tokenTask = Task.Run(() => w.DoWorkToken(mainToken), mainToken);
sourceTask = Task.Run(() => w.DoWorkSource(mainCancelationTokenSource), mainCancelationTokenSource.Token);
}
public void Cancel()
{
mainCancelationTokenSource.Cancel();
}
private void MainCanceled()
{
try
{
tokenTask.Wait();
}
catch (Exception e)
{
}
try
{
sourceTask.Wait();
}
catch (Exception e)
{
}
}
}
class Workers
{
public void DoWorkToken(CancellationToken mainToken)
{
CancellationTokenSource linkedCts = CancellationTokenSource.CreateLinkedTokenSource(mainToken);
CancellationToken linkedToken = linkedCts.Token;
while (!linkedToken.IsCancellationRequested)
{
Random r = new Random();
Task.Delay(200 * r.Next(1, 11)).Wait();
}
linkedToken.ThrowIfCancellationRequested();
}
public void DoWorkSource(CancellationTokenSource mainCts)
{
CancellationTokenSource linkedCts = CancellationTokenSource.CreateLinkedTokenSource(mainCts.Token);
while (!linkedCts.Token.IsCancellationRequested)
{
Random r = new Random();
Task.Delay(200 * r.Next(1, 11)).Wait();
}
linkedCts.Token.ThrowIfCancellationRequested();
}
}
Чтобы запустить этот код из основного метода консольного приложения:
class Program
{
static void Main(string[] args)
{
Manager manager = new Manager();
manager.Start();
//Console.ReadKey();
Thread.Sleep(5000);
manager.Cancel();
}
}
Спасибо за помощь!