Обычно я не ставил вопрос с ответом, но на этот раз я хотел бы привлечь некоторое внимание к тому, что, на мой взгляд, может быть неясной, но общей проблемой. Это было вызвано этим вопросом, так как тогда я просмотрел свой собственный старый код и нашел, что на него тоже повлияло это.
Ниже приведен код и ждет две задачи: task1
и task2
, которые почти идентичны. task1
отличается от task2
тем, что он запускает бесконечный цикл. IMO, оба случая довольно типичны для некоторых реальных сценариев выполнения работы с привязкой к ЦП.
using System;
using System.Threading;
using System.Threading.Tasks;
namespace ConsoleApplication
{
public class Program
{
static async Task TestAsync()
{
var ct = new CancellationTokenSource(millisecondsDelay: 1000);
var token = ct.Token;
// start task1
var task1 = Task.Run(() =>
{
for (var i = 0; ; i++)
{
Thread.Sleep(i); // simulate work item #i
token.ThrowIfCancellationRequested();
}
});
// start task2
var task2 = Task.Run(() =>
{
for (var i = 0; i < 1000; i++)
{
Thread.Sleep(i); // simulate work item #i
token.ThrowIfCancellationRequested();
}
});
// await task1
try
{
await task1;
}
catch (Exception ex)
{
Console.WriteLine(new { task = "task1", ex.Message, task1.Status });
}
// await task2
try
{
await task2;
}
catch (Exception ex)
{
Console.WriteLine(new { task = "task2", ex.Message, task2.Status });
}
}
public static void Main(string[] args)
{
TestAsync().Wait();
Console.WriteLine("Enter to exit...");
Console.ReadLine();
}
}
}
Скрипка здесь. Выход:
{ task = task1, Message = The operation was canceled., Status = Canceled } { task = task2, Message = The operation was canceled., Status = Faulted }
Почему статус task1
равен Cancelled
, но статус task2
равен Faulted
? Примечание. В обоих случаях я не передаю token
в качестве второго параметра до Task.Run
.