Код ниже был добавлен в недавно созданный проект 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).
