2016-01-24 2 views
-1

Я делаю некоторые вещи IoT с датчиками, и я пытаюсь изменить значения температуры. Проблема в том, что я не могу изменить свойство, которое у меня есть в классе. Я использую интерфейс, класс Sensors и класс, который реализует интерфейс. Посмотрите на приведенный ниже код. Беллоу метод класса ChangeTemp(), только для испытанияC# WCF не может изменить свойство класса

public string ChangeTemp() 
{ 
    TemperaturaZrak = 12; //property value change - class sensor 
    return TemperaturaZrak.ToString();//just for test if really change value 
} 

контракт Определение интерфейса

[OperationContract] 
string changeProperty(); 

класса, которые реализуют интерфейс

public string changeProperty() 
{ 
    return sr.ChangeTemp(); //web service return new temperature? 
} 

датчики Full класса

[DataContract(Name ="SmartRoomClass")] 
public class SmartRoomClass 
{ 
    private double t1; 
    private double t2; 
    [DataMember(Name = "temperaturaZrak")] 
    public double TemperaturaZrak //getter,setter 
    { 
     get; 
     set; 
    } 

    public SmartRoomClass() //constructor 
    { 
     TemperaturaZrak = 15; 
    } 

    public void CheckTemperature1(double t1, double t2) 
    { 
     if (TemperaturaZrak >= t1) 
     { 
      TemperaturaZrak = 26; 
     } 
     if (TemperaturaZrak <= t2) 
     { 
      TemperaturaZrak = 22; 
     } 
    } 
} 

служба

namespace vaja_2sua.Services 
{ 
    public class SmartRoom : ISmartRoom 
    { 
     SmartRoomClass sr = new SmartRoomClass(); 
     public void checkTemperature(double t1, double t2) 
     { 
      sr.CheckTemperature1(t1, t2); 
     } 

     public bool checkTemperature(double temperatura) 
     { 
      if (temperatura > 40) 
       return true; 
      else 
       return false; 
     } 

     public double getAirTemperature() 
     { 
      return sr.TemperaturaZrak; 
     } 
    } 
} 

Интерфейс

[ServiceContract(Name= "ISmartRoom")] 
public interface ISmartRoom 
{ 
    [OperationContract] 
    void checkTemperature(double t1, double t2); 

    [OperationContract(Name = "GetAirTemperature")] 
    double getAirTemperature(); 
} 

Я могу предоставить больше информации, если это необходимо. Приветствия.

+0

Да, нам нужна дополнительная информация о вашей проблеме. Вы пытались вызвать службу wcf и вернули старое значение? Или у вас была другая проблема? Обратите внимание, что экземпляры служб WCF могут создаваться при каждом вызове службы. Как вы добавляете класс класса в свою службу WCF? Нужно ли сохранять и хранить определенное состояние за каждый вызов? –

+0

Служба WCF возвращает мне то же значение, что и в конструкторе. – Ales

+0

Кажется, что ваш сеттер или геттер TemperaturaZrak работает неправильно. См. Полный код службы (мне нужен конструктор) и класс Sensors (с свойством, backfield и другими деталями). –

ответ

1

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

Есть 3 варианта услуг инстансов WCF, которая определяет InstanceContextMode перечисление:

  • PerCall - новый экземпляр службы будет создает в каждом вызове.
  • PerSession - для каждого сеанса имеется только один экземпляр с собственным состоянием .
  • Одиночный - у вас всегда будет тот же экземпляр с его контекстом.

Вы можете указать поведение службы WCF с помощью ServiceBehaviorAttribute и InstanceContextMode.

Используйте свойство InstanceContextMode, чтобы указать, когда создаются новые объекты службы . Поскольку объект услуги не связан напрямую с подключенным каналом связи, срок службы объектов не зависит от времени жизни канала между клиентом и приложением обслуживания. Значение по умолчанию PerSession инструктирует приложение-службу для создания нового объекта службы, когда между клиентом и службой устанавливается новый сеанс связи. Последующие вызовы в том же сеансе обрабатываются одним и тем же объектом .

В вашем примере выполняются следующие действия:

  • Пользователь вызывает checkTemperature метод WCF службы.
  • На сервере создается новый канал и новый сеанс.
  • Новый экземпляр класса SmartRoom. Когда построено SmartRoom , он создает новый экземпляр класса SmartRoomClass , потому что класс инициализирует свои поля экземпляра и propertis (строка).
  • Метод checkTemperature фактически вызывается на сервере. Он называет SmartRoomClass.CheckTemperature1(...) метод, который меняет TemperaturaZrak значение.
  • Выполнение этого метода завершается, и ваше клиентское приложение завершает сеанс (или просто не хранит его).
  • Пользовательские вызовы getAirTemperature метод службы WCF.
  • На сервере создается новый канал и новый сеанс.
  • Новый экземплярSmartRoomкласс экземпляр. При построении SmartRoom также создается новый экземпляр классаSmartRoomClass класс с новым значениемTemperaturaZrak!
  • Метод getAirTemperature фактически вызывается на сервере. Он возвращает значение 15, потому что новый экземпляр SmartRoomClass инициализирован значением .

Теперь вы знаете, почему температура по умолчанию была возвращена с getAirTemperature.

Как исправить это поведение в соответствии с вашими потребностями? Сначала вы можете сохранить экземпляр клиента службы wcf из вызова для вызова, например, в this example.

Но открытый канал не всегда является хорошей идеей, поскольку он требует дополнительных ресурсов сервера. Лучше всего изменить свой SmartRoomClass и сохранить значение TemperaturaZrak не только в памяти, но и в хранилище данных, которое также может сохранять разные значения для каждого пользователя или наоборот. Самый простой способ - использовать файл или Isolated Storage.

+0

Большое вам спасибо! Теперь я понимаю проблему. Я проверю это изолированное хранилище, звучит достаточно хорошо. Я напишу здесь, если мне нужна дополнительная помощь. – Ales

+0

@Ales существует множество различных реализаций, методов и технологий для хранения данных на сервере, и нет 1 правильного ответа на то, что использовать. Изолированное хранилище - это просто одно из простых решений, но лучше выбрать его на основе бизнес-требований и сценариев. Например, изолированное хранилище не переносится с сервера на сервер, и вам нужно будет написать собственную миграцию. Кроме того, вы можете хранить больше данных для каждого пользователя и использовать реляционную модель или другие параметры. Удачи. –

+0

На данный момент я решил свою проблему. Все, что мне нужно было сделать, это поставить «статический» перед SmartRoomClass sr = new SmartRoomClass(); ». Я не знаю ... это сделало волшебство. – Ales

Смежные вопросы