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方法获取的,以防止超过 1 个线程访问它,如下所示:

[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 方法的第三点
  4. Thread 2:运行 Execute 方法的第 4 点 -> Wierd!
  5. Thread 1: 运行 Execute 方法的第 4 点

出乎意料的是,在方法的中间,这个新线程就在这个点上,并执行了整个方法的一部分。这个新线程(Thread 2)甚至根本没有到达第 1、第 2 和第 3 点)

有时它也会按以下顺序发生:

  1. Thread 1: 运行 Execute 方法的第一个点
  2. Thread 1: 运行 Execute 方法的第 2 点
  3. Thread 2:运行 Execute 方法的第 4 点 -> Weird!
  4. Thread 1:运行 Execute 方法的第三点。
  5. Thread 1:运行 Execute 方法的第 4 点。

所有这些都是从日志文件中读取和写入的,而不是通过调试。当我进行调试时,一切似乎都很好。

我使用了 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

线程 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 回答