Чрезвычайно странная ошибка со свойством в C#

У меня есть определенное приложение, которое вводит информацию в объект после сравнения новой информации со старой. Это похоже на

set
{
    oldval=_value;
    _value=value;
    if (some comparison logic)
        raiseEvent();
}

Все это происходит в фоновом потоке в бесконечном цикле, который периодически спит в течение 100 мс. Действительно странно то, что он работает в первый раз, логика сравнения оказывается верной и возникает событие. После этого информация продолжает поступать, она продолжает поступать в объект, я знаю это, потому что я установил MessageBoxes для постоянного отображения старых и новых значений, но это как если бы он каким-то образом обошел предложение set! Я установил окно сообщения в начале предложения, оно просто не всплывает! Это действительно странно, поскольку я уверен, что значение постоянно обновляется.

Какие-нибудь мысли?


Да, я знаю, но, к сожалению, я мало что могу показать ... Позвольте мне еще раз объяснить общую структуру: У меня есть отдельный фоновый поток, выполняющий бесконечный цикл. Этот цикл непрерывно извлекает данные из объекта Data, который обновляется целым другим набором потоков. Все это, конечно, синхронизируется с Monitor.Enter и Exit. Данные, извлеченные из объекта Data, затем вводятся в объект Comparer.

while(true)
{
    Thread.Sleep(100);
    Monitor.Enter(Data);
    Comparer.Value = Data.Value;
    Monitor.Exit(Data);
}

Comparer.Value - это свойство, о котором я упоминал в первом посте. Это действительно довольно странно, так как я установил MessageBox в конце цикла:

MessageBox.Show(Comparer.Value + " - " + Data.Value);

и значения действительно обновляются, это просто как-то обходит предложение set, что невозможно ... Это действительно странно.

И Роб, цикл не выполняет никаких проверок, он просто имитирует поток информации в Comparer.Value; Предложение set содержит логику сравнения.

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


Хорошо, я решил проблему, видимо, мой вопрос был неправильным, проблема была в другом месте. Спасибо за помощь, вопрос может быть закрыт.

Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
0
0
466
6

Ответы 6

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

Без значимого кода мы можем только догадываться. В частности, если добавление MessageBox в начало Set не появляется, то, вероятно, проблема в вызывающем коде (не в этом).

Тем не менее, некоторые мысли - особенно если у вас несколько потоков:

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

Этого не могло быть; без некоторого примера кода мы действительно не сможем помочь.

Я выделил сходство потоков жирным шрифтом, так как это очень вероятная проблема, если ваш рабочий вносит изменения, которые (через событие) пользовательский интерфейс отслеживает; обработчик событий пользовательского интерфейса должен переключается на поток пользовательского интерфейса для обновления пользовательского интерфейса:

void SomeHandler(object sender, EventArgs args)
{
    this.Invoke((MethodInvoker)delegate {
       this.Text = "Something happened";
    });
}

Предыдущие ответы абсолютно верны в том, что вам нужно предоставить больше информации.

Но можно спросить Почему, что вы так делаете? Конечно, ваша бизнес-модель просто вызовет событие, когда значение установлено, почему существует фоновый поток, который периодически проверяет?

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

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

Marc Gravell 28.10.2008 11:18

Поскольку событие возникает в фоновом потоке, все ваши обработчики событий запускаются в этом (фоновом) потоке. Ваш код правильно с этим справляется?

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

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

Спам System.Diagnostic.Debug.WriteLine вокруг вместо ящиков сообщений. Они не изменяют (или, по крайней мере, в минимальной степени) не изменяют поток инструкций и не имеют проблем с потоками (кроме возможного плохого вывода).

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

В-третьих, что такое «(некоторая логика сравнения)»?

Если это простой (oldval! = _Value), перепишите его как

set
{
 if (_value != value)
 {
  _value=value;
  RaiseSomeEvent();
 }
}

он чище, и у вас нет шансов изменить _value без возникновения события (кроме подписанных обработчиков ..).

В противном случае выражение «(некоторая логика сравнения)», скорее всего, является ошибочным местоположением.

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