【问题标题】:Extremely Weird Bug with a property in C# [closed]在 C# 中有一个属性的非常奇怪的错误 [关闭]
【发布时间】:2008-10-28 07:59:00
【问题描述】:

在将新信息与旧信息进行比较后,我有一个将信息输入对象的应用程序。 它类似于

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 子句,这是不可能的...... 这真的很奇怪。

Rob,循环不做任何检查,它只是将信息流模拟到 Comparer.Value 中;它的 set 子句包含比较逻辑。

bh213,确实是这样,但我无法判断,因为在进行任何有意义的检查之前比较就停止了。


好的,我已经解决了问题,显然我的问题是错误的,问题出在另一个地方。 感谢您的帮助,问题可能已关闭。

【问题讨论】:

    标签: c# .net properties


    【解决方案1】:

    没有一些有意义的代码,我们只能猜测。特别是如果在 Set 的开头添加 MessageBox 没有出现,那么很可能问题出在调用代码上(不是这个)。

    不过,有些想法 - 特别是因为您有多个线程:

    • 某处是否存在线程竞赛?是否应该同步一些代码?
    • 工作人员是否获得了非易失性值的陈旧副本?
    • 线程亲和性:是否涉及工作人员和 UI 的事情很无聊?
    • 您确定您有正确的实例(即触发事件的对象是否可能与您正在侦听的对象不同)?

    这些都不是;如果没有一些示例代码,我们将无能为力。

    我用粗体标记了线程关联,因为如果您的工作人员正在(通过事件)UI 正在侦听的更改,这很可能是一个问题; UI 事件处理程序必须切换到 UI 线程来更新 UI:

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

    【讨论】:

      【解决方案2】:

      之前的答案完全正确,您需要提供更多信息。

      但是我能问一下为什么你会这样做吗?你的业务模型肯定会在设置值时引发一个事件,为什么会有一个后台线程运行来间歇性地检查?

      也许我只是遗漏了一些东西,但似乎这里可能存在导致 真正的问题的设计缺陷。

      【讨论】:

      • 听起来工人正在提供更改,而不是关注它们。这就是为什么我特别担心线程关联性。
      【解决方案3】:

      垃圾邮件 System.Diagnostic.Debug.WriteLine 而不是消息框。 这些不会(或至少它们只在最低限度内)改变指令流并且没有线程问题(除了可能的错误输出)。

      此外,从描述来看,带有一些精心放置的断点的简单调试会话可能会有所帮助。

      三、什么是“(一些比较逻辑)”?

      如果是简单的 (oldval != _value) 重写为

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

      它更干净,如果没有引发事件(除了没有订阅的处理程序..),您就没有机会更改 _value。

      否则“(一些比较逻辑)”表达式可能是错误的位置。

      【讨论】:

        【解决方案4】:

        您确实需要提供更多信息。我们在这里得到的只是一些伪代码。尝试提出一个 short but complete program 来证明问题。

        【讨论】:

          【解决方案5】:

          由于在后台线程上引发了事件,因此所有事件处理程序都在该(后台)线程上运行。你的代码处理正确吗?

          【讨论】:

            【解决方案6】:

            正如其他人所说,您确实需要创建一个小的工作示例来显示问题。

            在创建此示例应用程序时,您甚至可能会自己注意到问题的根源。

            【讨论】:

              猜你喜欢
              • 1970-01-01
              • 1970-01-01
              • 2012-08-10
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 2016-07-07
              • 1970-01-01
              相关资源
              最近更新 更多