2012-09-18 11 views
5

Mam dwie metody w WCF Służby powiedziećGlobalna zmienna pomiędzy dwoma WCF Metod

Method1() 
{ 
_currentValue = 10; 
} 

Method2() 
{ 
return _currentValue; 
} 

Mam sytuacji, w której trzeba ustawić wartość w method1() i odczytać go w Method2().

Próbowałem używać zmiennej static, takiej jak public static int _currentValue, mogłem odczytać wartość ustawioną w Method1() w Method2().

Ale problem polega na tym, że ta zmienna powinna reagować jak osobna zmienna instancji dla każdego wykonanego żądania. czyli teraz poniżej jest problem

Przeglądarka 1:

- Method1() is called 
    => sets _currentValue = 10; 
- Method2() is called 
    => returns _currentValue = 10; 

Browser 2:

- Method2() is called 
    => returns _currentValue = 10; 

Właściwie ustawiona wartość jest Przeglądarka 1 jest statyczny, więc w przeglądarce 2 ta sama wartość zostanie pobrana.

To, co próbuję zaimplementować, to zmienna powinna zachowywać się jak nowa instancja dla każdego wykonanego żądania (podczas wywoływania z każdej przeglądarki). Co powinienem użyć w tym przypadku? Sesja?

+0

dlaczego to ma być 'static'? –

+0

to nie musi być, próbuję mieć zmienną, która jest dostępna między dwiema metodami wcf .. powinienem użyć jakiejś innej koncepcji, takiej jak sesja? – balanv

+0

tak - myślę, że chcesz instancji na sesję. –

Odpowiedz

3

Będziesz potrzebował jakiegoś mechanizmu korelacji, ponieważ masz dwie zupełnie różne sesje wywołujące różne metody. Polecam więc używanie klucza prywatnego, który znają obydwaj rozmówcy.

To jest trochę niemożliwe dla mnie, aby wiedzieć, co ten klucz może być, ponieważ nie mogę naprawdę zebrać cokolwiek z twojego pytania, więc tylko ty to wiesz, ale prostym faktem jest to, że będziesz potrzebował korelacji. Teraz, kiedy ustalisz, czego mogą użyć, możesz zrobić coś takiego.

public class SessionState 
{ 
    private Dictionary<string, int> Cache { get; set; } 

    public SessionState() 
    { 
     this.Cache = new Dictionary<string, int>(); 
    } 

    public void SetCachedValue(string key, int val) 
    { 
     if (!this.Cache.ContainsKey(key)) 
     { 
      this.Cache.Add(key, val); 
     } 
     else 
     { 
      this.Cache[key] = val; 
     } 
    } 

    public int GetCachedValue(string key) 
    { 
     if (!this.Cache.ContainsKey(key)) 
     { 
      return -1; 
     } 

     return this.Cache[key]; 
    } 
} 

public class Service1 
{ 
    private static sessionState = new SessionState(); 

    public void Method1(string privateKey) 
    { 
     sessionState.SetCachedValue(privateKey, {some integer value}); 
    } 

    public int Method2(string privateKey) 
    { 
     return sessionState.GetCachedValue(privateKey); 
    } 
} 
2

Utworzono zmienną static i właśnie to powoduje problem. static oznacza, że ​​każda instancja klasy dzieli zmienną, ale wszystko, czego naprawdę potrzebujesz, to zmienna zadeklarowana poza swoimi metodami, na przykład:

private int _currentValue; 

Method1() 
{ 
    _currentValue = 10; 
} 

Method2() 
{ 
    return _currentValue; 
} 

zmienna ta zostanie reated oddzielnie dla każdej instancji klasy - zachowanie ta wartość między żądaniami dla danego użytkownika jest osobnym problemem. (Sesja jest jednym z możliwych rozwiązań.)

3

Wygląda na to, że konieczne może być użycie trybu kontekstowego instancji sesji dla usługi WCF. Umożliwi to zachowanie stanu na podstawie sesji, więc zmienne członkowskie w instancji usługi będą się utrzymywać między wywołaniami metod z tej samej instancji serwera proxy. Ponieważ każdy użytkownik ma własną sesję, stan instancji usługi zależy od użytkownika.

Sprawdź ten artykuł, aby uzyskać więcej informacji: http://msdn.microsoft.com/en-us/magazine/cc163590.aspx#S2

0

Wygląda jak stary wątek, ale w przypadku ktoś jest nadal zainteresowany, to można osiągnąć tylko przez prosząc WCF uruchomić jedno wystąpienie usługi. Dodaj następujący wiersz (dekorator) do definicji klasy [ServiceBehavior (InstanceContextMode = InstanceContextMode.Single)]

Jeśli chcesz tylko dla zachowania tej samej sesji, ale nie w poprzek klientów to można oznaczyć go jako na sesję następującym zachowanie podczas eksploatacji [ServiceBehavior (InstanceContextMode = InstanceContextMode.PerSession)]

Innym rozwiązaniem jest jedno połączenie, które jest ustawienie domyślne. [ServiceBehavior (InstanceContextMode = InstanceContextMode.PerCall)]