为什么CancellationToken它被实现为一个结构?
结构体毕竟是值类型,那么这个机制是如何实现的呢?
static void Main(string[] args)
{
CancellationTokenSource cancelTokenSource = new CancellationTokenSource();
CancellationToken token = cancelTokenSource.Token;
Task task1 = new Task(() => Factorial(5, token));
task1.Start();
cancelTokenSource.Cancel();
}
static void Factorial(int x, CancellationToken token)
{
int result = 1;
for (int i = 1; i <= x; i++)
{
if (token.IsCancellationRequested)
{
Console.WriteLine("Операция прервана токеном");
return;
}
result *= i;
Console.WriteLine("Факториал числа {0} равен {1}", i, result);
Thread.Sleep(5000);
}
}
毕竟结构体是值类型,传递参数时会创建对象的副本CancellationToken token
为效率而战。
在大多数情况下,是的,
CancellationToken它很可能是一个类,一个分配不会改变任何东西,因为多线程代码通常对几个额外的小分配不重要。但毕竟
CancellationToken认为取消的一般机制。在某些情况下,分配对用户至关重要。如果它CancellationToken是一个类,那么在这些情况下,框架的用户将不得不使用自己编写的结构,更糟糕的是,他们将无法使用库方法。CancellationToken(例如,如果用户想要传递给期望的方法,CancellationToken.None因为他们需要速度并且不需要取消。)因此,开发人员决定让我们这些用户的生活更轻松,并使其
CancellationToken成为一种结构。关于机制的实现:是的,开发人员违反了语义,
CancellationToken它的行为就像一个典型的类,而不是一个典型的结构。他们以这种方式实现了它。其中CancellationToken有一个字段private CancellationTokenSource m_source;(指向源的链接)。在相等性检查中,它比较m_source,并且在复制时m_source,它也被复制,因此令牌的副本的行为与原始令牌一样,因此与它无法区分。特别是,如果原始令牌被取消,那么它的副本也被取消。