下面的代码已添加到新创建的 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)
,但没有意识到这个例子只是因为存在而成功。