使用带有异步的Thread.CurrentPrincipal并等待?

时间:2017-12-27 11:01:49

标签: c# multithreading asynchronous

考虑以下代码,在单个主要执行线程上设置ClaimsPrincipal,然后运行任务并尝试访问ClaimsPrincipal:

internal static class AsyncHelper
{
    private static readonly TaskFactory MyTaskFactory = new
        TaskFactory(CancellationToken.None,
            TaskCreationOptions.None,
            TaskContinuationOptions.None,
            TaskScheduler.Default);

    public static void RunSync(Func<Task> func)
    {
        AsyncHelper.MyTaskFactory
                .StartNew<Task>(func)
                .Unwrap()
                .GetAwaiter()
                .GetResult();
    }
}

Thread.CurrentThread.ManagedThreadId 2
Thread.CurrentPrincipal?.Identity?.Name bob
        Inside Async Method - Thread.CurrentThread.ManagedThreadId 3
        Inside Async Method - Thread.CurrentPrincipal?.Identity?.Name null
        Inside Async Method - Thread.CurrentThread.ManagedThreadId 3
        Inside Async Method - Thread.CurrentPrincipal?.Identity?.Name null
Thread.CurrentThread.ManagedThreadId 2
Thread.CurrentPrincipal?.Identity?.Name bob
Press any key to exit

程序的输出是

Thread.CurrentThread.ManagedThreadId 2
Thread.CurrentPrincipal?.Identity?.Name bob
        Inside Async Method - Thread.CurrentThread.ManagedThreadId 3
        Inside Async Method - Thread.CurrentPrincipal?.Identity?.Name bob <--- Notice here
        Inside Async Method - Thread.CurrentThread.ManagedThreadId 3
        Inside Async Method - Thread.CurrentPrincipal?.Identity?.Name bob <--- Notice here
Thread.CurrentThread.ManagedThreadId 2
Thread.CurrentPrincipal?.Identity?.Name bob
Press any key to exit

想到 我会看到的是:

ClaimsPrincipal

在主线程上设置的{{1}}发生了什么(在此特定输出ManagedThreadId 2的情况下)?为什么在复制ExecutionContext时,ClaimsPrincipal不会被复制到另一个线程?

更新 :。Net目标框架是.NET Core 2.0。

更新2 :此问题似乎特定于.NET Core。使用相同的代码,而是针对.NET 4.6.1框架,我得到了我期望的输出。

1 个答案:

答案 0 :(得分:1)

您不能依赖线程属性,因为线程分配给任务的详细信息取决于具体的ThreadScheduler(https://msdn.microsoft.com/en-us/library/system.threading.tasks.taskscheduler(v=vs.110).aspx)。有许多不同的ThreadScheduler实现。

有一个选项可以实现您自己的自定义TaskScheduler,您可以在其中将Thread.CurrentPrincipal设置为您的值,但最好不要依赖所有线程属性,而不是依赖于任务级别&#34;。