[c#] 대기 후 HttpContext.Current가 null 인 이유는 무엇입니까?

다음 테스트 WebAPI 코드가 있으며 프로덕션에서 WebAPI를 사용하지 않지만이 질문에 대한 토론 때문에 만들었습니다. WebAPI 비동기 질문

어쨌든 문제가되는 WebAPI 메서드는 다음과 같습니다.

public async Task<string> Get(int id)
{
    var x = HttpContext.Current;
    if (x == null)
    {
        // not thrown
        throw new ArgumentException("HttpContext.Current is null");
    }

    await Task.Run(() => { Task.Delay(500); id = 3; });

    x = HttpContext.Current;
    if (x == null)
    {
        // thrown
        throw new ArgumentException("HttpContext.Current is null");
    }

    return "value";
}

두 번째 예외는 await완료 될 때 HttpContext.Current스레드 정적 변수가 더 이상 적절한 값으로 해석되지 않는 다른 스레드에있을 가능성이 높기 때문에 두 번째 예외가 예상됩니다 . 이제 동기화 컨텍스트를 기반으로 실제로 대기 후 동일한 스레드로 다시 돌아 가야 할 수 있지만 테스트에서 멋진 작업을 수행하지 않습니다. 이것은 단지 평범하고 순진한 await.

다른 질문에 대한 의견에서 나는 HttpContext.Current기다림 후에 해결해야한다고 들었습니다 . 이 질문에 대해 같은 것을 나타내는 또 다른 의견이 있습니다. 그래서 무엇이 사실입니까? 해결해야합니까? 난 더 생각하지,하지만 난이 때문에 권위있는 대답 싶어 async하고 await나는 확실한 아무것도 찾을 수없는 새로운 충분히이입니다.

요약 : HttpContext.Current잠재적 null으로 await?



답변

ASP.NET 4.5 애플리케이션을 작성하고 4.5 를 대상으로하고 있는지 확인하십시오 . async그리고 await당신은 4.5에서 실행되지 않는 ASP.NET에 정의되지 않은 동작을 하고 새로운 “작업 친화적 인”동기화 컨텍스트를 사용하고 있습니다.

특히 다음 중 하나를 수행해야합니다.

  • 설정 httpRuntime.targetFramework하기 위해 4.5, 또는
  • 에서 appSettings로 설정 aspnet:UseTaskFriendlySynchronizationContext합니다 true.

자세한 정보는 여기에서 확인할 수 있습니다 .


답변

@StephenCleary가 올바르게 지적했듯이 web.config에 다음이 필요합니다.

<httpRuntime targetFramework="4.5" />

이 문제를 처음 해결할 때 위의 솔루션 전체 검색을 수행하고 모든 웹 프로젝트에 있는지 확인하고 신속하게 범인으로 무시했습니다. 결국 그 검색 결과를 전체 컨텍스트에서 살펴 보게되었습니다.

<!--
  For a description of web.config changes for .NET 4.5 see http://go.microsoft.com/fwlink/?LinkId=235367.

  The following attributes can be set on the <httpRuntime> tag.
    <system.Web>
      <httpRuntime targetFramework="4.5" />
    </system.Web>
-->

도.

레슨 : 웹 프로젝트를 4.5로 업그레이드하는 경우에도 해당 설정을 수동으로 가져와야합니다.


답변

내 테스트에 결함이 있거나 여기에 누락 된 web.config 요소가있어 HttpContext.Current가 대기 후 올바르게 해결됩니까?

당신의 테스트는 결함이없고 HttpContext.Current는 당신이 기다릴 때 ASP.NET Web API에서 기다릴 때이 기다림을 따르는 코드가 기다림 전에 존재했던 올바른 HttpContext를 전달하도록 보장하기 때문에 기다림 후에 null이되어서는 안됩니다.


답변

최근에이 문제를 만났습니다. Stephen이 명시 적으로 설정하지 않으면 대상 프레임 워크가이 문제를 일으킬 수 있다고 지적했듯이.

제 경우에는 웹 API가 버전 4.6.2로 마이그레이션되었지만 런타임 대상 프레임 워크가 웹 구성에 지정되지 않았기 때문에 기본적으로 <system.web> 태그 내에 누락되었습니다.

실행중인 프레임 워크 버전에 대해 의문이있는 경우이 방법이 도움이 될 수 있습니다. 웹 API 메서드에 다음 줄을 추가하고 중단 점을 설정하여 런타임에 현재로드 된 유형을 확인하고 레거시 구현이 아닌지 확인합니다.

다음이 표시되어야합니다 (AspNetSynchronizationContext).

여기에 이미지 설명 입력

LegazyAspNetSynchronizationContext (대상 프레임 워크를 추가하기 전에 확인한 내용) 대신 :

여기에 이미지 설명 입력

소스 코드 ( https://referencesource.microsoft.com/#system.web/LegacyAspNetSynchronizationContext.cs )로 이동하면이 인터페이스의 레거시 구현에 비동기 지원이 없음을 알 수 있습니다.

여기에 이미지 설명 입력

문제의 원인을 찾는 데 많은 시간을 보냈고 Stephen의 답변이 많은 도움이되었습니다. 이 답변이 문제에 대한 추가 정보를 제공하기를 바랍니다.


답변