다음을 통해 공유


스레드 로컬 스토리지: Thread-Relative 정적 필드 및 데이터 슬롯

관리되는 TLS(스레드 로컬 스토리지)를 사용하여 스레드 및 애플리케이션 도메인에 고유한 데이터를 저장할 수 있습니다. .NET은 관리되는 TLS를 사용하는 두 가지 방법, 즉 스레드 상대 정적 필드와 데이터 슬롯을 제공합니다.

  • 컴파일 시간에 정확한 요구 사항을 예상할 수 있는 경우 스레드 상대 정적 필드(Visual Basic의 스레드 상대 Shared 필드)를 사용합니다. 스레드 상대 정적 필드는 최상의 성능을 제공합니다. 또한 컴파일 시간 형식 검사의 이점을 제공합니다.

  • 실제 요구 사항이 런타임에만 검색될 수 있는 경우 데이터 슬롯을 사용합니다. 데이터 슬롯은 스레드 상대 정적 필드보다 더 느리고 사용하기 어려우며 데이터는 형식 Object으로 저장되므로 사용하기 전에 올바른 형식으로 캐스팅해야 합니다.

관리되지 않는 C++에서는 슬롯을 동적으로 할당하고 TlsAlloc 스레드 상대 스토리지에 변수를 할당해야 한다고 선언하는 데 사용합니다__declspec(thread). 스레드 상대 정적 필드 및 데이터 슬롯은 이 동작의 관리되는 버전을 제공합니다.

System.Threading.ThreadLocal<T> 클래스를 사용하여 개체가 처음 사용될 때 지연 초기화되는 스레드 로컬 개체를 만들 수 있습니다. 자세한 내용은 지연 초기화를 참조하세요.

관리되는 TLS의 데이터 고유성

스레드 상대 정적 필드 또는 데이터 슬롯을 사용하든 관리되는 TLS의 데이터는 스레드 및 애플리케이션 도메인의 조합에 고유합니다.

  • 두 스레드가 동일한 필드 또는 슬롯을 사용하는 경우에도 애플리케이션 도메인 내에서 한 스레드는 다른 스레드의 데이터를 수정할 수 없습니다.

  • 스레드가 여러 애플리케이션 도메인에서 동일한 필드 또는 슬롯에 액세스하는 경우 각 애플리케이션 도메인에서 별도의 값이 유지됩니다.

예를 들어 스레드가 스레드 상대 정적 필드의 값을 설정하고 다른 애플리케이션 도메인을 입력한 다음 필드 값을 검색하는 경우 두 번째 애플리케이션 도메인에서 검색되는 값은 첫 번째 애플리케이션 도메인의 값과 다릅니다. 두 번째 애플리케이션 도메인에서 필드에 대한 새 값을 설정해도 첫 번째 애플리케이션 도메인의 필드 값에는 영향을 주지 않습니다.

마찬가지로 스레드가 서로 다른 두 애플리케이션 도메인에서 동일한 명명된 데이터 슬롯을 가져오는 경우 첫 번째 애플리케이션 도메인의 데이터는 두 번째 애플리케이션 도메인의 데이터와 독립적으로 유지됩니다.

정적 필드 Thread-Relative

데이터 조각이 스레드 및 애플리케이션 도메인 조합에 항상 고유하다는 것을 알고 있는 경우 정적 필드에 특성을 적용 ThreadStaticAttribute 합니다. 다른 정적 필드를 사용하는 것처럼 필드를 사용합니다. 필드의 데이터는 해당 데이터를 사용하는 각 스레드에 고유합니다.

스레드 상대 정적 필드는 데이터 슬롯보다 더 나은 성능을 제공하며 컴파일 시간 형식 검사의 이점을 제공합니다.

클래스 생성자 코드는 필드에 액세스하는 첫 번째 컨텍스트의 첫 번째 스레드에서 실행됩니다. 동일한 애플리케이션 도메인의 다른 모든 스레드 또는 컨텍스트에서 필드는 참조 형식인 경우 (nullVisual Basic에서) 또는 값 형식인 경우 기본값으로 초기화 Nothing 됩니다. 따라서 클래스 생성자를 사용하여 스레드 상대 정적 필드를 초기화해서는 안 됩니다. 대신 null 또는 Nothing으로 초기화된 상태로 간주하여 스레드 상대 정적 필드를 초기화하지 않도록 합니다.

데이터 슬롯

.NET은 스레드 및 애플리케이션 도메인의 조합에 고유한 동적 데이터 슬롯을 제공합니다. 데이터 슬롯에는 명명된 슬롯과 명명되지 않은 슬롯의 두 가지 유형이 있습니다. 둘 다 구조를 사용하여 구현됩니다 LocalDataStoreSlot .

명명된 슬롯과 명명되지 않은 슬롯 모두에서 정보를 설정하고 검색하려면 Thread.SetDataThread.GetData 메서드를 사용하세요. 이러한 메서드는 현재 실행 중인 스레드의 데이터에 대해 항상 작동하는 정적 메서드입니다.

명명된 슬롯은 이름 없는 슬롯에 대한 참조를 유지하는 대신 메서드에 이름을 GetNamedDataSlot 전달하여 필요할 때 슬롯을 검색할 수 있으므로 편리할 수 있습니다. 그러나 다른 구성 요소가 스레드 상대 스토리지에 동일한 이름을 사용하고 스레드가 구성 요소와 다른 구성 요소 모두에서 코드를 실행하는 경우 두 구성 요소가 서로의 데이터를 손상할 수 있습니다. (이 시나리오에서는 두 구성 요소가 동일한 애플리케이션 도메인에서 실행되고 있으며 동일한 데이터를 공유하도록 설계되지 않았다고 가정합니다.)

참고하십시오