Действие <T>делегат против обработчика события, связанного с удалением - PullRequest
4 голосов
/ 13 апреля 2011

Я ищу архитектурный совет, а также более глубокое понимание делегатов и лямбд (помимо необходимости исправить реальную проблему!)

У нас есть код, взаимодействующий с устройством (шкалой) через последовательный портпорт на кпк.Мы подключаем представление для получения данных с устройства.Поскольку только одно представление за раз «подключается» к нашему экземпляру масштаба, мы использовали свойство типа Action для обработки взаимодействия между экземпляром масштаба и представлением (вместо подписки на событие).Затем представление устанавливает это свойство как лямбду, которая берет значение из шкалы и изменяет пользовательский интерфейс.

Проблема, с которой мы сталкиваемся в настоящее время, заключается в утилизации нашего представления.Если масштаб в настоящее время отправляет данные (а мы находимся внутри обработчика действий), когда представление закрывается пользователем (когда мы принудительно выполняем Dispose, поскольку мы используем CF), приложение зависает: лямбда-действие Action никогда не завершает выполнение ANDПри удалении SerialPort зависает экземпляр Dispose of scale.

  1. Есть ли ключевое различие в том, как действие свойства класса обрабатывается в подобной ситуации по сравнению ссобытие?

  2. На основе подробностей журнала код находится в лямбда-выражении Action (который изменяет некоторые элементы пользовательского интерфейса), когда Dispose вызывается для представления.Они оба в потоке пользовательского интерфейса - как они могут работать одновременно?Разве я не выспался прошлой ночью?

  3. Кто-нибудь видит здесь какие-то плохие архитектурные решения, которые следует исправить?

Спасибо.Я могу попытаться привести здесь примеры кода, если описание не имеет достаточного смысла.

Ответы [ 2 ]

2 голосов
/ 13 апреля 2011

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

Но все это звучит как проблема тупика / параллелизма. Вместо непосредственного закрытия последовательного порта, используйте сигнал на время обработчика действия (который, вероятно, одновременно работает в другом потоке - проверьте это снова), чтобы вы могли изящно дождаться его завершения перед закрытием порта.

1 голос
/ 13 апреля 2011
  1. Нет - событие на самом деле просто делегат, точно так же, как Действие

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

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

...