2012-10-31 4 views
0

나는 nettcpbinding 서비스를 가지고 있으며 Windows 서비스로 호스트하고 있습니다. 서비스는 네트워크에서 작동해야하며 수신 메시지는 100 개 이상의 클라이언트에서 처리됩니다.WCF 서비스의 모든 세션에 액세스 할 수있는 속성을 만들려면 어떻게해야합니까?

문제점 : 모든 세션에서 액세스 할 수있는 속성이 있어야합니다. 예 :

class a 
{ 
    list<string> strList=new list<string>(); 

class b{} 
class c{} 
... 
} 

이 예제에서 모든 클래스는 strList에 액세스 할 수 있습니다. 나는 모든 세션이 그것에 접근 할 수있는 목록을 원한다. (목록에있는 것을 추가하거나 삭제할 수있다.)

서비스 구성이 버퍼링되고 보안되지 않습니다. 서비스 속성이 여기에 있습니다 :

[ServiceBehavior(InstanceContextMode = InstanceContextMode.PerSession)] 
[ServiceContract(SessionMode = SessionMode.Required)] 

편집 : 내가 만들고 싶지 않는 그 하나의 예를했다 클래스. 난 그냥 모든 세션이 그것에 액세스 할 수있는 목록이 필요합니다. 당신이 InstanceContextMode.PerSession 서비스를 서비스 클래스가 각 클라이언트마다 다음 각 클라이언트가 자신의 서비스 클래스를 만들 것입니다 지금은 내가 만든 각 세션은 하나의 공개 목록에 액세스 할 수 있습니다 싶습니다.

EDIT2 : 이 목록은 서버에 있으며 서버는 클라이언트에 목록을 보내지 않아도됩니다. 그것은 어떤 것을 계산하기위한 서버 변수입니다.

답변

3

당신은 예를 들어 서비스 클래스의 정적 속성을 사용할 수 있습니다 :

[ServiceBehavior(InstanceContextMode = InstanceContextMode.PerSession)] 
[ServiceContract(SessionMode = SessionMode.Required)] 
public class MyService : IMyService { 

    // this is your static data store which is accessible from all your sessions 
    private static List<string> strList = new List<string>(); 

    // an object to synchronize access to strList 
    private static object syncLock = new object(); 

    public void AddAction(string data) { 

     // be sure to synchronize access to the static member: 
     lock(syncLock) { 
      strList.Add(data); 
     } 
    } 

} 

WCF는 서비스에 연결하는 각각의 새로운 클라이언트이면 MyService의 새로운 인스턴스를 생성합니다. 모두 정적 속성에 액세스 할 수 있습니다.

0

나는 당신이 DataContract를 구축해야한다고 생각

예 :

[DataContract] 
    public class A 
    { 
    [DataMember] 
    list<string> strList { get; set; } 

    class B 
     { 
     } 

    class C 
     { 
     } 
    } 
+0

내 마지막 편집을 읽고 thx –

+0

을 작성하십시오. 그러면 ServiceContract를 작성하여 해당 목록을 클라이언트로 반환 할 수 있습니까? –

2

당신은 아마 당신의 들면, ConcurrencyMode 다중으로 설정하려는 것이고, 그 때문에 당신이, 당신은 멀티 스레드로 개체를 치료하기 위해 필요합니다 당신이 기본적으로 설정하고있는 것. 이 상황에서 교착 상태를 피하려면 여러 개의 잠금이 필요합니다. This MSDN article for details을 참조하십시오. 당신이 생각 컬렉션을 사용하여보고하는 경우

[SerivceBehavior(InstanceContextMode = InstanceContextMode.PerCall, ConcurrencyMode = ConcurrencyMode.Multiple)] 
class MyService : IMyContract 
{ 

//Here is your shared object 
static List<string> _strList = new List<string>(); 

//Only access the property for thread safety, not the variable 
static List<string> StrList 
{ 
    get 
    { 
     lock(typeof(MyService) 
     { 
      return _strList; 
     } 
    } 
    set 
    { 
     lock(typeof(MyService) 
     { 
      _strList = value; 
     } 
    } 
} 

void DoSomeThing() 
{ 
    lock(typeof(MyService)) 
    { 
     //Do something with your list here, other threads are blocked from accessing 
     // objects in lock 
     StrList.Add("Something"); 
    } 
} 
} 

이 멀티 스레드 액세스를 위해 만들어 짐에 따라, 나는 Concurrency Collection 개체를보고 제안했다. 이러한 객체는 잠금 기능이 필요하기 때문에 잠금 기능이 필요합니다. 잠금 기능을 포함하고 있기 때문에 나중에 잊어 버린 경우에 유용합니다.

편집 : 정보를 추가하기 만하면 잠금이 다른 스레드가 해당 잠금에서 코드를 실행하거나 잠긴 속성에 액세스하는 것을 차단합니다. 이러한 이유 때문에 모든 클라이언트의 속도를 늦출 수 있으므로 잠금 장치의 작동 시간을 길게하는 것은 권장되지 않습니다. 또한 PerCall로 설정된 InstanceContextMode는 EVERY CALL에 대한 서비스 클래스의 새 인스턴스를 서비스에 작성합니다. 반대로, 활동이없고 서비스 인스턴스가 모두 정리되거나 닫히면 공유 객체도 손실됩니다.

+0

당신의 대답을 위해 thx 나는 그것을 투표하지만 제 대답은 jan 대답이라고 생각합니다. –

관련 문제