Ограничение асинхронных событий для вызывающего объекта

2

в моем С# -Silverlight-3-приложении, я создал класс, который выполняет некоторые вычисления, которые используются в разных частях моей программы. Этот класс нуждается в данных из базы данных, поэтому он вызывает WCF-Service для получения данных. Структура класса выглядит следующим образом:

public class ConsumptionCalculation
{
  // Declare the event to notify subscribers, that the calculation has finished
  public delegate void HandlerConsumtionCalculationFinished(object sender, ConsumtionCalculationArgs args);
  public event HandlerConsumtionCalculationFinished CalculationFinished;

  public void Do(int id)
  {
    // call the WCF-Service
    DataContainer.instance.dataSource.GetConsumtionInfoAsync(id);
  }

  void dataSource_GetConsumtionInfoCompleted(object sender, GetConsumtionInfoCompletedEventArgs e)
  {
    // Receive the result of the WCF-Service call
    // do some calculation here and put the results in the variable 'args'

    // Raise an event to notify listeners, that the calculation is finished
    CalculationFinished(this, args);
  }
}

Объекты, которым нужен класс расчета, ссылаются на него и подписываются на событие CalculatedFinished.

public class IUseTheCalculation
{
  ConsumptionCalculation _calcObject;

  public IUseTheCalculation()
  {
    _calcObject = new ConsumptionCalculation();
    _calcObject.CalculationFinished += new HandlerConsumptionCalculationFinished(CalculationFinishedEvent);
  }

  private void CalculationFinishedEvent(object sender, ConsumptionCalculationArgs args)
  {
    // use the calculation to display data or write it to a file or whatever
  }
}

У меня есть несколько классов, таких как класс IUseTheCalculation, каждый из которых имеет свой собственный объект ConsumptionCalculation-Object.

Моя проблема заключается в следующем: Когда я вызываю Do-метод объекта ConsumptionCalculation в одном из классов, ВСЕ классы, имеющие ссылку на любой объект ConsumptionCalculation, получат итоговое событие CalculationFinished. Я думаю, это связано с тем, что все существующие объекты ConsuptionCalculation получают событие dataSource_GetConsumtionInfoCompleted из WCF-сервиса. Но я хочу, чтобы только вызывающий объект получил событие. Я предполагаю, что существует стандартный подход к этой проблеме, но я еще не мог понять. Как решить эту проблему?

Спасибо заранее, Франк

  • 0
    Есть причина, почему вы не создали Async Proxy, а не реализовали его самостоятельно?
  • 0
    Извините, но я не понимаю вашу точку зрения.
Теги:
wcf
events

2 ответа

1
Лучший ответ

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

Не могли бы вы использовать поле "id", чтобы различать различные вызывающие (а если нет, возможно добавить дополнительный параметр для этого)? Это не помешало бы другим классам получать уведомления, но они могли бы быстро проверить, есть ли уведомление для них, и быстро вернуться, если нет.

  • 0
    Я добавил декларацию к коду выше. Все объекты вычисления инициализируются оператором new в конструкторе соответствующих классов. Идея (или, может быть, лучше hashvalue, может быть?) Для различения вызывающих абонентов была идеей, которая у меня была, но она больше похожа на обходной путь, и я хотел посмотреть, есть ли более подход "наилучшей практики" ...
  • 0
    Я согласен, что использование хэша было бы обходным решением. Но я не видел эту проблему раньше, и видел, как она работает должным образом, поэтому вы можете не найти «лучшую практику», так как другие могут ее не видеть. Так что, если это ошибка, вам, возможно, придется обойти ее. Прежде чем сдаться, вы можете попробовать посмотреть в отладчике, чтобы убедиться, что вы на самом деле имеете дело с различными экземплярами объектов - если нет, вы можете исследовать, что происходит неправильно (например, какие объекты совпадают с ожидается, что они будут другими, и посмотрите, где они объявлены и т. д.).
Показать ещё 1 комментарий
1

Что выглядит для меня подозрительным:

   public void Do(int id)
   {
       // call the WCF-Service
        DataContainer.instance.dataSource.GetConsumtionInfoAsync(id);
   }

Как сообщается DataContainer.instance.dataSource связать этот идентификатор с этим экземпляром ConsumptionCalculation? Выполняется ли это в конструкторе?

public ConsumptionCalculation()
{
    DataContainer.instance.dataSource.OnGetConsumptionInfoComplete += CalculationFinishedEvent;
}

Как-то происходит соединение между DataContainer.instance и каждым экземпляром ConsumptionCalculation, и я уверен, вы подключаете каждый из них к одному событию.

  • 0
    Я хотел иметь один (Singleton) объект для подключения к / доступа к WCF-сервису. После избавления от этого идентификатора и создания экземпляра Service-Client для каждого класса, которому требуется доступ к сервису, все работает как положено.

Ещё вопросы

Сообщество Overcoder
Наверх
Меню