AsyncController를 종속성 주입과 혼합하려고합니다. 문제의 MVC 응용 프로그램은 비동기 웹 서비스 호출을 통해 거의 모든 데이터를 가져옵니다. TPL에서 Tasks의 비동기 작업을 래핑하고 이러한 작업이 완료되면 컨트롤러의 AsyncManager에 알립니다.AsyncManager.Sync없이 안전하게 ASP.NET 동기화 컨텍스트를 통해 작업 실행
때로는 쿠키를 추가하는 등의 작업을 계속 수행하면서 HttpContext를 눌러야합니다. Using an Asynchronous Controller in ASP.NET MVC에 따라이 작업을 수행하는 올바른 방법은 AsyncManager.Sync
메서드를 호출하는 것입니다. 그러면 HttpContext를 비롯한 ASP.NET 스레드 컨텍스트가 현재 스레드에 전파되고 콜백이 실행 된 다음 이전 컨텍스트가 복원됩니다.
그러나 그 기사는 말한다 :
동작을 보증되지 ASP.NET의 통제하에 이미 스레드에서 동기화()를 호출.
컨트롤러에서 작업을 모두 수행하면 문제가되지 않습니다. 일반적으로 연속에서 사용해야 할 스레드를 알고 있기 때문입니다. 하지만 내가하려는 것은 비동기 데이터 액세스와 비동기 컨트롤러 사이에 중간 계층을 만드는 것입니다. 그래서 이것도 비동기입니다. 모든 것은 DI 컨테이너에 의해 배선되어 있습니다.
이전과 같이 호출 체인의 일부 구성 요소는 "현재"HttpContext를 사용해야합니다. 예를 들어 로그온 후에 싱글 사인온 (SSO) 서비스에서 얻은 "세션"토큰을 저장하려고합니다. 그 일을하는 추상화는 ISessionStore입니다. 응답에 쿠키를 넣거나 요청에서 쿠키를 가져 오는 CookieSessionStore를 생각해보십시오. 나는이 함께 볼 수있는
두 가지 문제 :
- 구성 요소는 AsyncManager에 액세스 할 수 또는 그들이 컨트롤러에서 사용하고 모른다.
- 구성 요소는 호출되는 스레드를 알지 못하므로 AsyncManager.Sync 또는 이와 동등한 기능은 이론적으로 문제가됩니다.
내가 기본적으로 요청의 시작 부분에 TaskScheduler.FromCurrentSynchronizationContext()
을 잡고 객체를 주입하고, # 1를 해결하기 위해, 그리고 작업이 인수로 HttpContextBase 복용, 그 스케줄러 시작을 통해 작업을 호출 할 수 있습니다.
즉, 내 구성 요소에서, 나는 비슷한 호출 할 수 있습니다 : 나는 아직이 어떤 문제를 발견하지 않은
MySyncObject.Sync(httpContext => /* Add a cookie or something else */);
을,하지만 난 문제 # 2에 대한 걱정. Reflector에서 AsyncManager
과 SynchronizationContextTaskScheduler
을 모두 보았고 비슷하게 작동하여 ASP.NET SynchronizationContext
에서 콜백을 실행합니다. 그리고 그게 날 무서워 :)
인라인 경우 동기화 작업을 수행하는 대신 작업 스케줄러 구현이 직접 호출하는 것을 보았을 때 조금의 희망이있었습니다. 그러나 유감스럽게도 이것은 보통 Task.Start(scheduler)
코드 경로를 통해 발생하지 않는 것 같습니다. 오히려, 작업은 시작하기 전에 기다리는 것과 같은 다른 상황에서 인라인 될 수 있습니다.
그래서 내 질문은 : 나는이 방법으로 여기 문제로 실행하는 것
- 건가요?
- 더 좋은 방법이 있습니까?
- 스레드 안전성이없는 HttpContext에 대한 액세스를 직렬화하기 만하면이 시나리오에서 동기화의 유용성이 있습니까? 즉, 대신 스레드로부터 안전한 HttpContextBase 래퍼 (ick)를 사용할 수 있습니까?
'Task.Start (scheduler)'를 사용하면, 충분히 빨리'Wait()'하면 인라인 될 수 있습니다. 물론 우리는 멀티 스레딩에 대해 이야기하고 있습니다. 따라서 "즉시"는 "충분히 빠르지"않을 수도 있습니다. – svick
흠 나는 그것을 보지 못한다. 물론 .NET 4.5를 지금 설치 했으므로 누가 알 수 있습니까? :) –