I remember that a long time ago, .NET threading was implemented in such a way that it should, in theory, support Win32 fibers. It's why all the low-level .NET APIs don't use the OS thread IDs, but instead have their own IDs, and require explicit mapping.
I believe that it was abandoned as a supported scenario a while ago, though. But you can still see artifacts of that in the docs, e.g.:
https://msdn.microsoft.com/en-us/library/system.threading.th...
"The value of the ManagedThreadId property does not vary over time, even if unmanaged code that hosts the common language runtime implements the thread as a fiber."
Then there's `async`/`await`[1], which is built on top of tasks.
[0] https://msdn.microsoft.com/en-us/library/system.threading.ta...
[1] https://msdn.microsoft.com/en-us/library/mt674882.aspx