为什么线程突然运行一个方法的一部分
本文关键字:一个 方法 一部分 线程 突然 运行 为什么 | 更新日期: 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%左右,我想这已经足够了。情况如下:
Thread 1
:运行Execute方法的第一个点Thread 1
:运行Execute方法的第二个点Thread 1
:运行Execute方法的第三点Thread 2
:运行Execute方法的第4点->WierdThread 1
:运行Execute方法的第4点
出乎意料的是,在方法的中间,这个新线程正好出现在这个点上,并执行整个方法的一部分。这个新线程(Thread 2
)做NOT甚至去到第一、第二和第三点)
有时也会按以下顺序发生:
Thread 1
:运行Execute方法的第一个点Thread 1
:运行Execute方法的第二个点Thread 2
:运行Execute方法的第4点->怪异Thread 1
:运行Execute方法的第三个点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集合上运行,主线程会立即更改值(这显然是我的错误,我通过克隆更新的对象来解决它),并导致其他线程在应该具有原始值时使用这个修改的对象。
这种情况看起来像是我问的一个问题。
非常感谢你的帮助。