AsyncLocal의 의미는 논리적 호출 컨텍스트와 어떻게 다릅니 까?
.NET 4.6 AsyncLocal<T>
에는 비동기 제어 흐름을 따라 주변 데이터를 흐름을위한 클래스가 도입되었습니다 . 나는 이전 CallContext.LogicalGet/SetData
에이 목적으로 사용 했으며, 두 가지가 의미 론적으로 다른지 그리고 어떤 방식으로 (강력한 타이핑과 문자열 키에 대한 의존성 부족과 같은 명백한 API 차이를 넘어서) 궁금합니다.
의미는 거의 동일합니다. 둘 다에 저장되고 ExecutionContext
비동기 호출을 통해 흐릅니다.
차이점은 API 변경 (설명한대로)과 값 변경에 대한 콜백을 등록하는 기능입니다.
기술적 CallContext
으로는 의 데이터가 사전에 보관되고 추가 작업없이 해당 참조 만 복사 CallContext.Clone
되는 동안 복사 (사용 ) 할 때마다 복제되므로 구현에 큰 차이 가 있습니다.AsyncLocal
ExecutionContext._localValues
AsyncLocal
의 값 을 변경할 때 업데이트가 현재 흐름에만 영향을 미치도록하기 위해 새 사전이 생성되고 모든 기존 값이 새 사전에 얕게 복사됩니다.
이 차이 AsyncLocal
는 사용되는 위치에 따라 성능에 좋을 수도 있고 나쁠 수도 있습니다 .
이제 주석에서 언급 한 Hans Passant CallContext
는 원래 원격 용으로 만들어졌고 원격 기능이 지원되지 않는 곳에서는 사용할 수 없습니다 (예 : .Net Core). 아마 AsyncLocal
프레임 워크에 추가 된 이유 일 것입니다 .
#if FEATURE_REMOTING
public LogicalCallContext.Reader LogicalCallContext
{
[SecurityCritical]
get { return new LogicalCallContext.Reader(IsNull ? null : m_ec.LogicalCallContext); }
}
public IllogicalCallContext.Reader IllogicalCallContext
{
[SecurityCritical]
get { return new IllogicalCallContext.Reader(IsNull ? null : m_ec.IllogicalCallContext); }
}
#endif
참고 : AsyncLocal
Visual Studio SDK에는 기본적으로 CallContext
개념이 얼마나 유사한 지 보여주는 래퍼 인 Microsoft.VisualStudio.Threading이 있습니다.
두 가지 의미가 다른지 그리고 어떤 방식으로 다른지 궁금합니다.
볼, 모두 할 수있는 일에서 CallContext
와 AsyncLocal
의존 내부적으로 ExecutionContext
돌며 자신의 내부 데이터를 저장합니다 Dictionary
. 후자는 비동기 호출에 대한 또 다른 수준의 간접적 인 방향을 추가하는 것 같습니다. CallContext
.NET Remoting 이후로 존재했으며 지금까지 실제 대안이 없었던 비동기 호출간에 데이터를 이동하는 편리한 방법이었습니다.
내가 발견 할 수있는 가장 큰 차이점은 AsyncLocal
이제 기본 저장된 값이 ExecutionContext
스위치에 의해 변경 되거나 기존 값을 대체하여 명시 적으로 변경 될 때 콜백을 통해 알림에 등록 할 수 있다는 것 입니다.
// AsyncLocal<T> also provides optional notifications
// when the value associated with the current thread
// changes, either because it was explicitly changed
// by setting the Value property, or implicitly changed
// when the thread encountered an "await" or other context transition.
// For example, we might want our
// current culture to be communicated to the OS as well:
static AsyncLocal<Culture> s_currentCulture = new AsyncLocal<Culture>(
args =>
{
NativeMethods.SetThreadCulture(args.CurrentValue.LCID);
});
그 외에 하나는에 System.Threading
있고 다른 하나는에 있으며 System.Runtime.Remoting
전자는 CoreCLR에서 지원됩니다.
또한 AsyncLocal
얕은 copy-on-write 의미론 SetLogicalData
이 있는 것 같지 않으므로 데이터가 복사되지 않고 호출간에 흐릅니다.
타이밍에 의미 론적 차이가있는 것 같습니다.
CallContext를 사용하면 자식 스레드 / 태스크 / 비동기 메서드에 대한 컨텍스트가 설정 될 때 (예 : Task.Factory.StartNew (), Task.Run () 또는 비동기 메서드가 호출 될 때) 컨텍스트 변경이 발생합니다.
AsyncLocal을 사용하면 자식 스레드 / 태스크 / 비동기 메서드가 실제로 실행을 시작할 때 컨텍스트 변경 (변경 알림 콜백 호출)이 발생합니다.
특히 컨텍스트가 전환 될 때 컨텍스트 개체를 복제하려는 경우 타이밍 차이가 흥미로울 수 있습니다. 다른 메커니즘을 사용하면 다른 콘텐츠가 복제 될 수 있습니다. CallContext를 사용하면 자식 스레드 / 태스크가 생성되거나 비동기 메서드가 호출 될 때 콘텐츠를 복제합니다. 그러나 AsyncLocal을 사용하면 자식 스레드 / 태스크 / 비동기 메서드가 실행을 시작할 때 콘텐츠를 복제하면 컨텍스트 개체의 콘텐츠가 부모 스레드에 의해 변경 될 수 있습니다.
'IT TIP' 카테고리의 다른 글
ssh가있는 SCP : scp를 사용하여 Windows에서 원격 서버로 로컬 파일 복사 (0) | 2020.12.25 |
---|---|
숨겨진 입력이 true / false 대신 value =“value”를 쓰는 이유는 무엇입니까? (0) | 2020.12.25 |
Intellij-메서드 참조로 대체 가능 (0) | 2020.12.25 |
Visual Studio의 알파벳순 방법 (0) | 2020.12.25 |
XSD-두 가지 속성 중 하나가 필요합니까? (0) | 2020.12.25 |