2

私は本当に何かに行き詰まっており、この場所だけが答えを得ることができます. 最初から最後まで読んでいただければ幸いです。

私は以下のようなことをするメソッドを持っています:

public void Execute(Data data)
{
    bool IsOk = false;
    //1st point
    IsOk = Check1();

    //2nd point
    if(IsOk)
      IsOk = Check2();

    //3nd point
    if(IsOk)
      IsOk = Check3();

    //4th point
    if(IsOk)
       SendMessage();

}

以下のように、複数のスレッドがデータ オブジェクトにアクセスするのを防ぐために、データ オブジェクトはメソッドによって取得さSTATICれます。

[MethodImpl(MethodImplOptions.Synchronized)]
public static DataCollection GetDataColl()
{
   //By syncronizing, I'm guaranteeing every data is unique.
   DataCollection Result = new DataCollection();
   Result = GetDataFromDatabase();//Changing status in order to prevent getting it again
   return Result;
}

そして、この後、以下のメソッドを に与えてTHREADSを処理しますDataCollection

//When invoked, creates the threads that runs my actual processing method
private void btnStart_Click(object sender, EventArgs e)
{
   for(int i= 1; i <= 2; i++ )
   {
      Thread ProcessThread = new Thread(ProcessData);
      ProcessThread.Start();
   }
}

//Process the data
private void ProcessData()
{
   DataCollection Coll = GetDataColl(); //GetDataColl is static, threadsafe that can be invoked only by 1 thread at a time method.

   //Foreach through data and execute the PROBLEMATIC method "Execute" at the beginning
   foreach(Data dta in Coll)
      Execute(dta); //The problem occurs in this method
}

問題は時々発生しますが、常にではありませんが、一度に約20%を与えることができます。これで十分だと思います. 何が起こるかは次のとおりです。

  1. Thread 1: Execute メソッドの最初のポイントを実行します
  2. Thread 1: Execute メソッドの 2 番目のポイントを実行します。
  3. Thread 1: Execute メソッドの 3 番目のポイントを実行します。
  4. Thread 2: Execute メソッドの 4 番目のポイントを実行します -> 奇妙な!
  5. Thread 1: Execute メソッドの 4 番目のポイントを実行します。

突然、メソッドの途中で、この新しいスレッドが RIGHT AT THIS POINT に来て、メソッド全体の一部を実行します。この新しいスレッド ( Thread 2) は、1 番目、2 番目、3 番目のポイントにもまったく行きません)

場合によっては、次の順序で発生することもあります。

  1. Thread 1: Execute メソッドの最初のポイントを実行します
  2. Thread 1: Execute メソッドの 2 番目のポイントを実行します。
  3. Thread 2: Execute メソッドの 4 番目のポイントを実行します -> 変です!
  4. Thread 1: Execute メソッドの 3 番目のポイントを実行します。
  5. Thread 1: Execute メソッドの 4 番目のポイントを実行します。

これらはすべて、 debugではなく、ログ ファイルからここで読み書きされます。デバッグを行うと、すべて問題ないようです。

私は log4net を使用しました。これは、何が起こったかの簡単なサンプルです。

2013-02-19 09:53:02,057 [39] DataId: 4356502 - Check1
2013-02-19 09:53:02,088 [39] DataId: 4356502 - Check2
2013-02-19 09:53:02,088 [39] DataId: 4356502 - Check3
2013-02-19 09:53:02,542 [39] DataId: 4356502 - Send
2013-02-19 09:53:02,573 [46] DataId: 4356502 - Send

スレッド No 46 は、チェック 1、2、3 にもまったく該当しませんでした。

4

2 に答える 2

0

少し変更はありますが、コードを試してみましたが、問題なく動作しているようです。出力の上位を確認し、スレッド [46] がスレッド [39] の前に実行されていないことを確認してから、保留にします。

th1 - Check 1 example string 235236
th1 - Check 2 example string 235236 <- thread1 gets to #2 and stops
th2 - Check 1 example string 235236
th2 - Check 2 example string 235236
th2 - Check 3 example string 235236 <- thread2 gets to #3
th1 - Check 3 example string 235236 <- thread1 starts up again, at #3
th2 - Check 4 example string 235236 <- thread4 then finishes off with #4
th2 - Check 1 example string 135236
th2 - Check 2 example string 135236
th2 - Check 3 example string 135236
th1 - Check 4 example string 235236 <- thread1 appears and finishes #4
th2 - Check 4 example string 135236
于 2013-02-19T10:11:11.873 に答える
0

ここで問題を解決しましたが、

メイン スレッドが開始すると、シングルトン メッセージ コレクションを保持する STATIC 変数が使用されます。他のスレッドがこのシングルトン コレクションを実行しようとするため、メイン スレッドは一時的に値を変更し (これは明らかに私の間違いであり、更新されたオブジェクトを複製することで解決しました)、他のスレッドが元の値を持つべきときにこの変更されたオブジェクトを使用する結果になります。 .

この状況は、私が質問した問題のように見えました。

助けてくれてありがとう。

于 2013-04-18T08:24:47.137 に答える