programing

현재 WCF 호출에 대한 데이터를 어디에 저장할까요?

projobs 2021. 1. 15. 07:31
반응형

현재 WCF 호출에 대한 데이터를 어디에 저장할까요? ThreadStatic은 안전한가요?


내 서비스가 실행되는 동안 많은 클래스가 User.Current (즉, 내 사용자 클래스)에 액세스해야합니다. _currentUser를 [ThreadStatic]변수 에 안전하게 저장할 수 있습니까 ? WCF는 스레드를 재사용합니까? 그렇다면 언제 ThreadStatic 데이터를 정리합니까? ThreadStatic을 사용하는 것이 안전하지 않은 경우 해당 데이터를 어디에 넣어야합니까? OperationContext.Current 내에 그런 종류의 데이터를 저장할 수있는 장소가 있습니까?

2009 년 12 월 14 일 편집 : ThreadStatic 변수를 사용하는 것이 안전하지 않다고 주장 할 수 있습니다. WCF 스레드는 스레드 풀에 있으며 ThreadStatic 변수는 다시 초기화되지 않습니다.


.NET Framework 구현을 제안 하는 블로그 게시물IExtension<T>있습니다. 토론을 살펴볼 수도 있습니다 .

다음은 제안 된 구현입니다.

public class WcfOperationContext : IExtension<OperationContext>
{
    private readonly IDictionary<string, object> items;

    private WcfOperationContext()
    {
        items = new Dictionary<string, object>();
    }

    public IDictionary<string, object> Items
    {
        get { return items; }
    }

    public static WcfOperationContext Current
    {
        get
        {
            WcfOperationContext context = OperationContext.Current.Extensions.Find<WcfOperationContext>();
            if (context == null)
            {
                context = new WcfOperationContext();
                OperationContext.Current.Extensions.Add(context);
            }
            return context;
        }
    }

    public void Attach(OperationContext owner) { }
    public void Detach(OperationContext owner) { }
}

다음과 같이 사용할 수 있습니다.

WcfOperationContext.Current.Items["user"] = _currentUser;
var user = WcfOperationContext.Current.Items["user"] as MyUser;

드라이브 클래스를 추가하지 않는 대체 솔루션입니다.

    OperationContext operationContext = OperationContext.Current;
    operationContext.IncomingMessageProperties.Add("SessionKey", "ABCDEFG");

가치를 얻으려면

var ccc = aaa.IncomingMessageProperties["SessionKey"];

그게 다야


다중 스레드 전환으로 비동기 호출을 할 때 데이터 또는 현재 컨텍스트를 놓친다는 것을 발견했습니다. 이러한 시나리오를 처리하기 위해 CallContext를 사용할 수 있습니다. .NET Remoting에서 사용되어야하지만 이러한 시나리오에서도 작동해야합니다.

CallContext에서 데이터를 설정합니다.

DataObject data = new DataObject() { RequestId = "1234" };
CallContext.SetData("DataSet", data);

CallContext에서 공유 데이터 검색 :

var data = CallContext.GetData("DataSet") as DataObject;

// Shared data object has to implement ILogicalThreadAffinative

public class DataObject : ILogicalThreadAffinative
{
  public string Message { get; set; }
  public string Status { get; set; }
}

왜 ILogicalThreadAffinative인가?

다른 AppDomain의 개체에 대한 원격 메서드 호출이 수행되면 현재 CallContext 클래스는 호출과 함께 원격 위치로 이동하는 LogicalCallContext를 생성합니다.

ILogicalThreadAffinative 인터페이스를 노출하고 CallContext에 저장된 개체 만 AppDomain 외부로 전파됩니다.

ReferenceURL : https://stackoverflow.com/questions/1895732/where-to-store-data-for-current-wcf-call-is-threadstatic-safe

반응형