0

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

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,我很漂亮,但我不知道,因为比较在任何有意义的检查完成之前就停止了。


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

4

6 回答 6

5

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

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

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

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

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

void SomeHandler(object sender, EventArgs args)
{
    this.Invoke((MethodInvoker)delegate {
       this.Text = "Something happened";
    });
}
于 2008-10-28T08:04:59.567 回答
2

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

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

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

于 2008-10-28T08:15:48.403 回答
2

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

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

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

如果它是一个简单的 (oldval != _value) 将其重写为

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

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

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

于 2008-10-28T08:42:31.720 回答
1

你真的需要提供更多信息。我们在这里得到的只是一些伪代码。尝试提出一个简短但完整的程序来演示该问题。

于 2008-10-28T08:00:58.683 回答
0

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

于 2008-10-28T08:19:13.717 回答
0

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

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

于 2008-10-28T08:30:34.427 回答