10

SharePoint/ASP.NET 환경에는 공통 인터페이스에서 파생되는 일련의 데이터 검색 자 클래스가 있습니다. WCF를 사용하여 다른 SharePoint 팜과 원격으로 통신 할 수있는 데이터 검색자를 만드는 작업이 할당되었습니다. 현재 구현 된 방법은 정적 생성자에서 싱글 톤 ChannelFactory<T>을 만든 다음 원격 데이터 검색 프로그램의 각 인스턴스에서 다시 사용하여 개별 프록시 인스턴스를 만드는 것입니다. ChannelFactory은 앱 도메인에서 한 번만 인스턴스화되고 생성은 guaranteed to be thread-safe이기 때문에 이것이 제대로 작동 할 것이라고 생각했습니다. 내 코드는 다음과 같습니다.싱글 톤 채널 팩터 리 <T> 만들기 및 클라이언트 연결 용으로 다시 사용

public class RemoteDataRetriever : IDataRetriever 
{ 
    protected static readonly ChannelFactory<IRemoteDataProvider> 
     RequestChannelFactory; 

    protected IRemoteDataProvider _channel; 

    static RemoteDataRetriever() 
    { 
     WSHttpBinding binding = new WSHttpBinding(
      SecurityMode.TransportWithMessageCredential, true); 

     binding.Security.Transport.ClientCredentialType = 
      HttpClientCredentialType.None; 

     binding.Security.Message.ClientCredentialType = 
      MessageCredentialType.Windows; 

     RequestChannelFactory = 
      new ChannelFactory<IRemoteDataProvider>(binding); 
    } 

    public RemoteDataRetriever(string endpointAddress) 
    { 
     _channel = RemoteDataRetriever.RequestChannelFactory. 
      CreateChannel(new EndpointAddress(endpointAddress)); 
    } 
} 

제 질문은 좋은 디자인입니까? ChannelFactory이 생성되면 스레드 안전성에 대해 걱정할 필요가 없다는 것을 알아 냈습니다. 왜냐하면 나는 단지 CreateChannel()을 호출하기 위해 사용하고 있었기 때문에 실수였습니다. 상태가 바뀌거나 그렇지 않으면 스레딩 문제를 일으킬 수있는 장면에서 펑키 한 무언가를하고 있습니까? 또한 수동으로 처리하는 일부 코드 (정적 종료 자?)를 ChannelFactory에 처리해야합니까? 아니면 IIS가 다시 부팅 될 때마다 모든 정리 작업을 수행 할 것이라고 가정 할 수 있습니까?

관련 : ChannelFactory Reuse Strategies만큼 당신의 "싱글"은 단순히 새로 건설 된 채널을 반환로

답변

3

"이 싱글 톤 디자인이 좋다"는 것이므로 구현 싱글 톤이 좋습니다. 스레드로부터 안전하며 ChannelFactory<T>은 스레드로부터 안전합니다.

리소스 정리에 대해 걱정할 필요가 없습니다. ChannelFactory<T>Microsoft's guidelines for implementing IDisposable 다음에 나왔다고 가정하면 어떤 종류의 누출에 문제가 없습니다. 응용 프로그램 도메인을 해체하면 가비지 수집이 생성되고 모든 항목이 정리됩니다. ChannelFactory<T>에있는 마무리 자 (finalizer)는 Dispose를 호출 할 때 일반적으로 수행하는 정리 작업을 수행합니다.

그러나 "내가 ChannelFactory<T>을 캐싱해야합니까?"라는 관점에서 볼 때, 현재 사용중인 .NET 버전을 나타내지 않으므로 말하기 어렵습니다. 그러나 가리키는 문서에서는 .NET 3.0 SP1 이상을 사용하는 경우 실제로이 작업을 수행 할 필요가 없음을 나타내며 클라이언트 코드에서 필요로하는 프록시를 만들 수 있습니다 (ClientBase<T>에서 파생 된 것으로 가정). 이런 공장 패턴을 통해서가 아니라.

+0

나는 똑같은 것을 나타내는 것처럼 보이는 das 금발 기사를 발견했다 - http://www.dasblonde.net/PermaLink.aspx?guid=c7922cb4-26d4-408b-b029-cfadd75ff954. 그러나, "당신을 위해 생성 된"이라는 단어는 ClientBase 전체에서 약간 벗어났습니다. 그래도 나는 네가 이걸 가지고 있다고 생각한다. –

+0

다른 WCF 문제에 대한 연구를 수행하는 동안 ClientBase 에 대해 ChannelFactory 을 선호하는 좋은 이유를 발견했습니다. - http://stackoverflow.com/questions/2252747/what-is-system-servicemodel-diagnostics-callbackexception-and-why-cant -i-handle –

+0

@Repo Man : 원한다면 예외를 재 포장하는 것이 좋은 이유가 아닌 이상 최선의 방법은 아닙니다. WCF에서 이러한 오류가 발생하는 경우 예외를 다시 적용 할 자격이 있다고 생각하지 않습니다. – casperOne

0

, 당신은 스레드 안전에 대해 걱정할 필요가 없습니다. 정적 선언에 휘발성 키워드를 던져서 컴파일러가 최적화를 방해하지 않도록 항상 정적 선언에 던져 넣을 수는 있지만이 경우에는 필요하지 않다고 생각합니다.

장기적인 유연성에 대해 질문 해보십시오. 예를 들어, 나중에이 CreateChannel 메소드에 상태를 추가하기로 결정했다면 어떻게 될까요? 아마도 최대 10 개의 채널을 만든 다음 그 후에 다시 사용하기 시작할 것입니다. 이 작업을 위해 싱글 톤을 쉽게 수정할 수 있습니까?

당신의 대답은 아마도 그렇습니다. 그렇다면 수직적으로 여러 서버로 확장한다면 어떨까요? 싱글 톤으로는 충분하지 않을 수도 있습니다. 인스턴스/서버간에 상태를 공유 할 수있는 방법이 필요합니다 (예 : 데이터베이스, 분산 캐시). 상태를 공유하기로 결정한 방법에 따라 정적 컨텍스트에서 수행하기가 어려울 수 있습니다.

0

this article, Daniel Vaughan은 채널 관리자를 사용하여 채널을 캐싱하고 ChannelFactory를 캐싱하지 않겠다고합니다. 우리는 지금까지 아무런 문제없이이 접근법을 사용 해왔다.

이렇게의 장점

은 다음과 같습니다

"는 채널이 오류 상태가되면 그것은 캐시에서 제거하고 요청 다음 때 다시 ..."

  • 보안 협상이 아니라 한 번 수행했습니다.
  • 각 사용시 채널을 명시 적으로 닫지 않아도됩니다.
  • 초기화 기능을 추가 할 수 있습니다.
  • 프록시가 서버와 통신 할 수 없으면 일찍 실패 할 수 있습니다.
+1

나는 그것이 오래되었다는 것을 안다. 그러나 이것도 효과적으로 ChannelFactory를 캐시하지 않을 것인가? 팩토리를 릴리스하면 채널이 닫히기 때문에 – Tracker1