Betrachten Sie den folgenden Code, der eine ClaimsPrincipal auf einem einzigen Haupt-Thread von Ausführungssätzen und führt dann eine Aufgabe und versucht, den ClaimsPrincipal zuzugreifen:Verwenden von Thread.CurrentPrincipal mit async und warten?
public class Program
{
public static void Main(string[] args)
{
//Setting the CurrentPrincipal on the main thread
Thread.CurrentPrincipal = new ClaimsPrincipal(new ClaimsIdentity(new[] { new Claim("name", "bob"), new Claim("role", "admin") }, "CUSTOM", "name", "role"));
Console.WriteLine("Thread.CurrentThread.ManagedThreadId " + Thread.CurrentThread.ManagedThreadId);
Console.WriteLine("Thread.CurrentPrincipal?.Identity?.Name " + (Thread.CurrentPrincipal?.Identity?.Name ?? "null"));
AsyncHelper.RunSync(
async() =>
{
Console.WriteLine("\tInside Async Method - Thread.CurrentThread.ManagedThreadId " + Thread.CurrentThread.ManagedThreadId);
Console.WriteLine("\tInside Async Method - Thread.CurrentPrincipal?.Identity?.Name " + (Thread.CurrentPrincipal?.Identity?.Name ?? "null"));
//Simulate long(er) running work
await Task.Delay(2000);
Console.WriteLine("\tInside Async Method - Thread.CurrentThread.ManagedThreadId " + Thread.CurrentThread.ManagedThreadId);
Console.WriteLine("\tInside Async Method - Thread.CurrentPrincipal?.Identity?.Name " + (Thread.CurrentPrincipal?.Identity?.Name ?? "null"));
});
Console.WriteLine("Thread.CurrentThread.ManagedThreadId " + Thread.CurrentThread.ManagedThreadId);
Console.WriteLine("Thread.CurrentPrincipal?.Identity?.Name " + (Thread.CurrentPrincipal?.Identity?.Name ?? "null"));
}
}
und
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();
}
}
Die Ausgabe des Programms
istThread.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
Was ich dachte ich sehen würde, ist dies:
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
Was ist mit dem ClaimsPrincipal
passiert, die auf der Haupt-Thread (bei dieser speziellen Ausgabe ManagedThreadId 2) eingestellt wurde? Warum wurde das ClaimsPrincipal nicht in den anderen Thread kopiert, als der ExecutionContext kopiert wurde?
Aktualisieren: Das .NET-Zielframework ist .NET Core 2.0.
Update 2: Dieses Problem scheint spezifisch für .NET Core zu sein. Wenn ich den gleichen Code verwende, aber stattdessen auf .NET 4.6.1 abziele, bekomme ich die erwartete Ausgabe.
Auf welcher .NET-Version führen Sie das aus? – Evk
Das Zielframework ist .NET Core 2.0. Ich denke, ich kann es in einer anderen Version versuchen und sehen, was passiert. –
Ich denke, auf vollen .net (wie 4.6) sollte es funktionieren, wie Sie erwarten – Evk