2016-08-15 2 views
3

비동기 메서드를 Global.asax의 Session_Start에서 호출하려면 어떻게해야합니까?Session_Start의 비동기 호출 메서드

Global.asax에 :

protected async Task Session_Start(object sender, EventArgs e) 
    {    
     Session.Timeout = 10; 

     // Do some asynch work 
     await repository.SetStatsInfo(System.DateTime.Now);    
    } 

비동기 방식 :

나는 기적으로 모두를 실행할 수 있습니다
public async Task SetStatsInfo(DateTime time) 
    { 
     using (ApplicationDBContext db = new ApplicationDBContext()) 
     { 
      // Do stuff (update visitors counter in db) .. 

      await db.SaveChangesAsync(); 

     } 
    } 

(void Session_Start 등을 정의하는) 노력하고 있습니다 만, 타격 있도록 비동기 방식을 선호하는 DB가 차단되지 않습니다.

Session_Start에 'async Task'와 같이 실행하면 session_start 내의 중단 점이 실행되지 않습니다.

+1

Chris가 올바르게 말했습니다. 단순히 비합리적으로 비동기가되는 이유는 없습니다. http://stackoverflow.com/a/38956850/2410379 –

+0

@DavidPine 그러나 '비동기 작업 '호출로만 사용할 수있는 API를 사용해야하는 경우 어떻게해야합니까? Stephen은 분명히 우리에게'GetAwaiter()'나'.Result'를 교착 상태의 위험 때문에 절대로 호출해서는 안된다는 것을 분명히했습니다. ASP는 어떻게 할 수 있습니까?NET 응용 프로그램의'Global''Application_Start' 메쏘드는 안전하게 async 메쏘드를 호출합니까? – Dai

답변

3

Global.asax에서 Session_Start과 같은 메소드는 특별합니다. 새로운 것을 정의 할 수는 없습니다. 프레임 워크는 실행되도록 프로그래밍 된 프레임 워크를 실행하며 비동기 버전은 제공되지 않습니다. 결과적으로 비동기 버전이 실행되지 않습니다.

그러나 실제로는 어쨌든 비동기가되는 것은 아닙니다. Global.asax 메서드는 응용 프로그램 풀의 시작 및 종료시 호출됩니다. 결과적으로 어쨌든 작업을 완료 할 때까지 아무 일도 일어나지 않기 때문에 어느 시점에서나 운영 스레드를 포기하는 것은 의미가 없습니다.

나는 당신이하고있는 일에 대해 확신 할 수는 없지만 코드의 주석에 따라 어쨌든이를 수행 할 수있는 적절한 곳이라고 생각하지는 않습니다. 이 코드는 요청 당 1 회만 실행됩니다. 요청 당 무언가를 원한다면 액션 필터와 같은 것을 살펴보십시오.

내가 이해에서
+0

당신이 주목했듯이, 새로운 세션이 시작될 때마다 db의 사이트 방문자 수를 업데이트하려고합니다 (이제는 이해함에 따라 동기화 실행 중임). 그런데 왜 Session_Start가 적절한 위치에 있지 않습니까? – Danielle

+0

Global.asax는 응용 프로그램 풀이 시작되거나 종료 될 때만 실행되기 때문에. 그 동안, 임의의 수의 다른 사용자에 대한 요청이 발생합니다. 일종의 방문자 추적 로직을 Session_Start에 추가하려는 경우 앱 풀이 시작될 때 한 번만 발생하며 구성 및 상태에 따라 앱 풀이 몇 시간, 며칠 또는 몇 주간 다시 시작하지 못할 수 있습니다. 서버의 분명히, 그것은 당신에게 매우 관련성있는 정보를주지 않을 것입니다. –

+0

'Application_Start'를 말하고 있습니까? 'Session_Start' 이벤트는 새로운 세션이 생성 될 때마다 시작됩니다 : [http://forums.asp.net/t/1230163.aspx?What+s+the+difference+between+Application_Start+and+Session_Start + in + Global + aspx +] (http://forums.asp.net/t/1230163.aspx?What+s+the+difference+between+Application_Start+and+Session_Start+in+Global+aspx+) – Danielle

4

가, ASP는 HttpContext.Current 개체에 액세스 할 수있는 유일한 스레드 지정된 스레드를 가지고 있으며, 차례로, 많은 Windows 응용 프로그램에서 UI 스레드와 같은 세션 (HttpContext.Current.Session)에 액세스 할 수 있습니다. 따라서 Session_Start 콜백에서 .Wait() 또는 .Result을 수행하면 알 수없는 결과가 제공되거나 프로세스가 교착 상태가됩니다.

는 실행의 작업의 스레드를 관리하는 여러 가지 방법이있을 것 같다, 기본 하나는, https://msdn.microsoft.com/en-us/library/system.threading.tasks.taskscheduler(v=vs.110).aspx#Sync

그러나 TaskScheduler 클래스를 통해 특정 동기화 컨텍스트로 실행되도록 작업을 지정되는 작업 클래스로 설계 되었기 때문에 APM (Asynchronous Programming Model) 패턴에서 나온 IAsyncResult을 구현하면 Task가 이전 APM 패턴 코드 (이전에 ASP가 작성된 것으로 이해 한 것)와 역 호환됩니다. https://blogs.msdn.microsoft.com/mazhou/2011/10/04/the-asynchronous-programming-models/ (표준 APM)이지만 약간의 통합 작업이 필요합니다.

.Net 4.5는 APM 스타일 HttpApplication을 지원하도록 비동기 작업을 수행하는 멋진 태스크 래퍼 (EventHandlerTaskAsyncHelper)를 도입했습니다. Session 객체에 액세스하기위한 모든 요구 사항을 충족하며 올바르게 실행됩니다. HttpApplication :

+1

FYI : The SessionStateModule은 읽기 전용 세션에서도 세션 상태를 강제로 저장하도록 Session_OnStart 동기화 처리기가 정의되었는지 여부를 확인하기 때문에 ReadOnly 세션이있는 페이지에는 빈 Session_OnStart 메서드가 필요합니다. http://referencesource.microsoft.com/#System.Web/State/ SessionStateModule.cs, 1292 –

관련 문제