Глобальная переменная между двумя методами WCF

У меня есть два метода в службе WCF сказать

Method1()
{
 _currentValue = 10;
}

Method2()
{
return _currentValue;
}

У меня есть ситуация, в которой мне нужно установить значение в Method1() и прочитать его в Method2().

Я пытался с помощью static переменная, как public static int _currentValueЯ мог бы прочитать значение, установленное в Method1() в Method2().

Но проблема в том, что я хочу, чтобы эта переменная реагировала как отдельная переменная экземпляра для каждого сделанного запроса. то есть, прямо сейчас ниже проблема

Браузер 1:

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

Браузер 2:

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

На самом деле значение, установленное в Браузере 1, является статическим, поэтому в Браузере 2 получается то же значение.

Я пытаюсь реализовать переменную, которая должна действовать как новый экземпляр для каждого сделанного запроса (при вызове из каждого браузера). Что я должен использовать в этом случае? сеанс?

5 ответов

Решение

Вам понадобится какой-то механизм для корреляции, потому что у вас есть две совершенно разные сессии, вызывающие разные методы. Поэтому я бы рекомендовал использовать закрытый ключ, который знают оба абонента.

Для меня немного невозможно понять, что это за ключ, потому что я ничего не могу понять из твоего вопроса, так что только ты это знаешь, но простой факт - тебе понадобится корреляция. Теперь, когда вы определите, что они могут использовать, вы можете сделать что-то вроде этого.

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);
    }
}

Похоже, вам может понадобиться использовать контекстный режим для каждого экземпляра сеанса для службы WCF. Это позволит вам поддерживать состояние для каждого сеанса, поэтому переменные-члены в экземпляре службы будут сохраняться между вызовами методов из одного и того же экземпляра прокси. Поскольку у каждого пользователя есть свой собственный сеанс, состояние экземпляра службы зависит от пользователя.

Проверьте эту статью для получения дополнительной информации: http://msdn.microsoft.com/en-us/magazine/cc163590.aspx

Вы сделали свою переменную staticи это то, что вызывает проблему. static означает, что каждый экземпляр вашего класса разделяет переменную, но все, что вам действительно нужно, это переменная, объявленная вне ваших методов, например:

private int _currentValue;

Method1() 
{ 
    _currentValue = 10; 
} 

Method2() 
{ 
    return _currentValue; 
} 

Эта переменная будет использоваться отдельно для каждого экземпляра вашего класса - сохранение этого значения между запросами для данного пользователя является отдельной проблемой. (Сессия является одним из возможных решений.)

Похоже на старый поток, но в случае, если кто-то все еще заинтересован, этого можно добиться, просто попросив WCF запустить один экземпляр вашего сервиса. Добавьте следующую строку (декоратор) к определению вашего класса [ServiceBehavior(InstanceContextMode = InstanceContextMode.Single)]

Если вы хотите, чтобы поведение было только для одного и того же сеанса, но не для разных клиентов, то вы можете пометить его как сеанс с помощью следующего поведения службы [ServiceBehavior(InstanceContextMode = InstanceContextMode.PerSession)]

Другой вариант - для вызова, который является параметром по умолчанию. [ServiceBehavior(InstanceContextMode = InstanceContextMode.PerCall)]

WCF предоставил три способа управления экземплярами службы WCF:

  • За звонок
  • Persession
  • Один экземпляр

Вы найдете лучшее решение, прочитав это

Три способа управления экземплярами WCF

Другие вопросы по тегам