为什么线程突然运行一个方法的一部分

本文关键字:一个 方法 一部分 线程 突然 运行 为什么 | 更新日期: 2023-09-27 17:59:59

我真的陷入了困境,这个地方是我唯一能得到答案的地方。我恳求你从头到尾读一遍。

我有一种方法可以做下面这样的事情:

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

出乎意料的是,在方法的中间,这个新线程正好出现在这个点上,并执行整个方法的一部分。这个新线程(Thread 2)做NOT甚至去到第一、第二和第三点)

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

  1. Thread 1:运行Execute方法的第一个点
  2. Thread 1:运行Execute方法的第二个点
  3. Thread 2:运行Execute方法的第4点->怪异
  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。

为什么线程突然运行一个方法的一部分

我已经尝试过您的代码,尽管有一些更改,但它似乎工作得很好。检查更高的输出,确保线程[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

我在这里解决了问题,

当主线程启动时,它使用一个静态变量来保存singleton消息集合。由于其他线程试图在这个singleton集合上运行,主线程会立即更改值(这显然是我的错误,我通过克隆更新的对象来解决它),并导致其他线程在应该具有原始值时使用这个修改的对象。

这种情况看起来像是我问的一个问题。

非常感谢你的帮助。