怎样才能默认(的CancellationToken)有相应的CancellationTokenSource有相应、CancellationToken、CancellationTokenSource

2023-09-04 02:41:35 作者:楼上有只喵

当我创建一个默认的的CancellationToken 我可以在该的CancellationToken 有一个 CancellationTokenSource 与之关联的存储在私有 m_source 字段:

When I create a default CancellationToken I can see in the debugger that the CancellationToken has a CancellationTokenSource associated with it which is stored in the private m_source field:

我想知道,怎么可能为结构的默认关键字的 将返回初始化为零或空,这取决于它们是否值或引用类型的和 CancellationTokenSource 是引用类型。

I am wondering how can that be as for structs the default keyword "will return each member of the struct initialized to zero or null depending on whether they are value or reference types" and CancellationTokenSource is a reference type.

的CancellationToken 拥有2构造不过是把这个字段设置,他们是不相关的默认(的CancellationToken)不调用构造函数和新的CancellationToken()(具有完全相同的行为)不调用构造函数监守结构不能有参数构造函数(的尚未)。

CancellationToken does have 2 constructors that set this field however they are irrelevant as default(CancellationToken) doesn't call constructors and new CancellationToken() (which has the exact same behavior) doesn't call a constructor becuase structs can't have parameterless constructors (yet).

推荐答案

默认(的CancellationToken)确实创建了一个的CancellationToken 其中, m_source 。你可以看到,通过使用反射获取私有字段的值:

default(CancellationToken) does create a CancellationToken where m_source is null. You can see that by getting the value of that private field using reflection:

Console.WriteLine(typeof (CancellationToken).
    GetField("m_source", BindingFlags.NonPublic | BindingFlags.Instance).
    GetValue(default(CancellationToken)) ?? "null");

输出:

null

您还可以看到,在调试器只消瘦相关领域:

You can also see that by pining only the relevant field in the debugger:

那么,会发生什么情况?

So, what happens?

调试器,以便显示的的CancellationToken ,访问它的属性逐一的内容。当内 CancellationTokenSource 的WaitHandle 属性创建和设置一个默认的 CancellationTokenSource 委托给它的的WaitHandle 属性之前:

The debugger, in order to display the contents of the CancellationToken, accesses its properties one by one. When the inner CancellationTokenSource is null the WaitHandle property creates and sets a default CancellationTokenSource before delegating to its WaitHandle property:

public WaitHandle WaitHandle
{
    get
    {
        if (m_source == null)
        {
             m_source = CancellationTokenSource.InternalGetStaticSource(false);
        }

        return m_source.WaitHandle;
    }
}

在最后,默认(的CancellationToken)新的CancellationToken 创建一个空的结构,其中 m_source 不过的通过查看调试器的结构,你正在填补这一领域使用默认 CancellationTokenSource 实例不能被取消。

In conclusion, default(CancellationToken) and new CancellationToken create an empty struct where m_source is null but by looking at the struct in the debugger you are filling that field with a default CancellationTokenSource instance that can't be cancelled.