0

新しい情報を古い情報と比較した後、情報をオブジェクトにフィードする特定のアプリケーションがあります。それは次のようになります

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

これはすべて、断続的に 100 ミリ秒スリープする無限ループのバックグラウンド スレッドで発生します。本当に奇妙な部分は、初めて機能し、比較ロジックが true になり、イベントが発生することです。その後、情報は流れ続け、オブジェクトに入り続けます。私は 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、その通りだと思いますが、意味のあるチェックが行われる前に比較が停止するため、わかりません。


わかりました、問題を解決しました。どうやら私の質問が間違っていたようです。問題はまったく別の場所にありました。ご協力ありがとうございます。質問はクローズされる可能性があります。

4

6 に答える 6

5

意味のあるコードがなければ、推測するしかありません。特に、MessageBox を Set の先頭に追加しても表示されない場合は、問題が呼び出し元のコード (これではない) にある可能性があります。

ただし、特に複数のスレッドがあるため、いくつかの考えがあります。

  • どこかにスレッドレースはありますか?コードの一部を同期する必要がありますか?
  • ワーカーは非揮発性値の古いコピーを取得していますか?
  • スレッド アフィニティ: ワーカーと 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

メッセージボックスの代わりにSystem.Diagnostic.Debug.WriteLineをスパムします。これらは命令フローを変更せず(または少なくとも最小限にしか変更しません)、スレッドの問題はありません(出力の不良の可能性は別として)。

また、説明から、慎重に配置されたブレークポイントを使用した単純なデバッグセッションが役立つ場合があるようです。

第三に、「(いくつかの比較ロジック)」とは何ですか?

単純な場合(oldval!= _value)、次のように書き直します

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

よりクリーンで、イベントが発生しない限り_valueが変更される可能性はありません(サブスクライブされたハンドラーは別として)。

それ以外の場合、「(いくつかの比較ロジック)」式はバグのある場所である可能性があります。

于 2008-10-28T08:42:31.720 に答える
2

より多くの情報を提供する必要があるという点で、以前の回答は完全に正しいです。

しかし、なぜこのようなことをしているのですか?確かにあなたのビジネスモデルは、値が設定されたときにイベントを発生させるだけですが、断続的にチェックするためにバックグラウンドスレッドが実行されているのはなぜですか?

多分私は何かが欠けているだけかもしれませんが、実際の問題を引き起こしている設計上の欠陥がここにある可能性が高いようです.

于 2008-10-28T08:15:48.403 に答える
1

あなたは本当にもっと情報を提供する必要があります。ここにあるのは疑似コードだけです。問題を示す短いが完全なプログラムを考え出すようにしてください。

于 2008-10-28T08:00:58.683 に答える
0

他の人が言ったように、あなたは本当に問題を示すために小さな実用的な例を作成する必要があります。

このサンプルアプリを作成しているときに、問題の原因に気付くかもしれません。

于 2008-10-28T08:30:34.427 に答える
0

イベントはバックグラウンド スレッドで発生しているため、すべてのイベント ハンドラーはその (バックグラウンド) スレッドで実行されています。あなたのコードはこれを正しく処理していますか?

于 2008-10-28T08:19:13.717 に答える