下面的代码已添加到新创建的 Visual Studio 2012 .NET 4.5 WebAPI 项目中。
我正在尝试以异步方法分配HttpContext.Current.User两者Thread.CurrentPrincipal。Thread.CurrentPrincipal除非执行await Task.Yield();(或其他任何异步操作)(传递true到AuthenticateAsync()将导致成功),否则流的分配不正确。
这是为什么?
using System.Security.Principal;
using System.Threading.Tasks;
using System.Web.Http;
namespace ExampleWebApi.Controllers
{
public class ValuesController : ApiController
{
public async Task GetAsync()
{
await AuthenticateAsync(false);
if (!(User is MyPrincipal))
{
throw new System.Exception("User is incorrect type.");
}
}
private static async Task AuthenticateAsync(bool yield)
{
if (yield)
{
// Why is this required?
await Task.Yield();
}
var principal = new MyPrincipal();
System.Web.HttpContext.Current.User = principal;
System.Threading.Thread.CurrentPrincipal = principal;
}
class MyPrincipal : GenericPrincipal
{
public MyPrincipal()
: base(new GenericIdentity("<name>"), new string[] {})
{
}
}
}
}
笔记:
await Task.Yield();可以出现在任何地方,也AuthenticateAsync()可以GetAsync()在调用之后移动到AuthenticateAsync()它仍然会成功。ApiController.User返回Thread.CurrentPrincipal。HttpContext.Current.User始终正确流动,即使没有await Task.Yield().Web.config包括<httpRuntime targetFramework="4.5"/>这意味着UseTaskFriendlySynchronizationContext。- 几天前我问了一个类似的问题
Task.Delay(1000),但没有意识到这个例子只是因为存在而成功。