var tokenSource2 = new CancellationTokenSource();
CancellationToken ct = tokenSource2.Token;
var task = Task.Factory.StartNew(() => {
Thread.Sleep(4000);
Console.WriteLine("Done");
ct.ThrowIfCancellationRequested();
}, ct);
Thread.Sleep(1000); Look here! <---
tokenSource2.Cancel();
try
{
Console.WriteLine("Wait");
task.Wait();
}
catch (Exception e)
{
Console.WriteLine("Task was canceled");
}
Не могу понять, почему, если я прокомментирую эту строку, все работает нормально, и исключение попадает в основной поток, но если я оставил эту строку, исключение выбрано в дочернем потоке строка с ct.ThrowIfCancellationRequested(); В обоих случаях есть один экземпляр токена отмены. Я новичок в multithreadin, поэтому я определенно пропущу что-то.Многопоточность - не понимаю ситуацию
Я попытался следующий код
static void Main(string[] args)
{
Thread.CurrentThread.Name = "Main";
Console.WriteLine("Name of the current thread is " + Thread.CurrentThread.Name);
var tokenSource2 = new CancellationTokenSource();
CancellationToken ct = tokenSource2.Token;
var task = Task.Factory.StartNew(() =>
{
Thread.Sleep(4000);
Console.WriteLine("Done");
try
{
ct.ThrowIfCancellationRequested(); // If I remove the try/catch here will be unhandled exception
}
catch (OperationCanceledException exp)
{
Console.WriteLine("Task was started then canceled");
}
}, ct);//ontinueWith(OnProcessImageEnded);
Thread.Sleep(1000);
tokenSource2.Cancel();
try
{
Console.WriteLine("Wait");
task.Wait();
}
catch (Exception e)
{
Console.WriteLine("Task was canceled");
}
Console.WriteLine("Task was finished");
Console.WriteLine(task.Status);
I исключение процесса в потоке данных задачи в настоящее время, но это приводит к положению задачи не должен быть установлен Отмененные. Я думаю, это потому, что теперь задача не может поймать исключение для ее обработки. Каков правильный путь?
Я нашел http://msdn.microsoft.com/en-us/library/ee191553.aspx этот пример, и у него такая же проблема! если мы нажмем на «c» во время выполнения, он выкинет необработанное исключение, когда мы попытаемся реконструировать, вызвав externalToken.ThrowIfCancellationRequested(); ... Я в замешательстве. Я использую x64 Win 7, 4.5 .net framework
ОК, но я думал, что поведение должно быть одинаковым. Почему у него есть смысл запускать задание или нет? Здесь docs info: Когда экземпляр задачи замечает исключение OperationCanceledException, созданное кодом пользователя, он сравнивает токен исключения с ассоциированным токеном (смотрите следующий комментарий, он слишком длинный для одного) –
(тот, который был передан API, который создал Задача). Если они одинаковы, а свойство IsCancellationRequested token возвращает true, задача интерпретирует это как подтверждение отмены и перехода в состояние «Отменено». Если вы не используете метод Wait или WaitAll для ожидания задачи, задача просто устанавливает свой статус в Canceled .--- Как я понимаю, это означает, что исключение не должно быть выбрано вообще, если не существует метода ожидания и должен быть брошен в основной поток в попытке с помощью метода Wait. Я взял его с http://msdn.microsoft.com/en-us/library/dd997396(v=vs.100).aspx –
Я думаю, что я не понял эту концепцию.Итак, я рассмотрел еще несколько примеров и понял, что если поток задачи не запущен, мы должны поймать исключение в вызывающем потоке, но если он уже запущен, нам нужно исключить исключение отмены в потоке задачи, не вызвав его. Я прав? –