2010-08-31 148 views
0

我有兩個工作線程。我用同一個鎖鎖定了兩個線程,但threadB在threadA之前得到執行,因此異常來了。我同時使用同一個鎖對象鎖定了線程。線程B正在使用委託函數。我該如何解決這個問題。C#線程鎖定失敗

詳細信息:


我有一個叫StateSimulation類。 裏面有兩個函數調用 一個)OnSimulationCollisionReset B)OnSimulationProgressEvent

執行是這樣的:

private void OnSimulationCollisionReset() 
{ 
    Thread XmlReset = new Thread(XmlResetFn); 
    XmlReset.Start(); 
} 

private void OnSimulationProgressEvent() 
{ 
    DataStoreSingleTon.Instance.IsResetCompleted = true; 
    Thread ThrdSimulnProgress = new Thread(SimulnProgress); 
    ThrdSimulnProgress.Start(); 
} 

其中SimulnProgress()XmlResetFn()如下:

private void SimulnProgress() 
{ 
    //uses a delegate 
    UIControlHandler.Instance.ShowSimulationProgress(); 
} 

private void XmlResetFn() 
{ 
    DataStoreSingleTon.Instance.GetFPBConfigurationInstance().ResetXmlAfterCollision(); 
} 

在哪個OnSimulationProgressEvent()正在使用委託功能。

showSimulationProgressResetXML...()使用相同的資源FPBArrayList

我的要求是SimulationProgressEvent()只能在Reset..()後才能使用。在resetXML..()我清除了FPBList。 在SimulationProgress()我訪問FPBList[i]其中i:0--->size; 我已鎖定兩個函數使用相同的鎖對象。我預計,reset()將首先完成。但進入復位後,在完成復位之前,showProgress()開始發生異常。

如何解決我的問題?

這是我如何鎖定功能

public System.Object lockThis = new System.Object(); 

private void SimulnProgress() 
{ 
    lock (lockThis) 
    { 
     UIControlHandler.Instance.ShowSimulationProgress(); 
    } 
} 

private void XmlResetFn() 
{ 
    lock (lockThis) 
    { 
     DataStoreSingleTon.Instance.GetFPBConfigurationInstance().ResetXmlAfterCollision(); 
    } 
} 

請給出一個解決方案。 Registers Nidhin KR

+0

請更好地格式化您的代碼,很難遵循它。您可能需要重新設計應用程序。 – jgauffin 2010-08-31 12:59:51

+0

什麼例外的是它被拋出? – 2010-08-31 13:02:42

回答

2

鎖旨在防止多個線程同時進入給定的代碼段。它們不打算以任何其他方式同步線程,例如,使它們按某種特定順序執行代碼。

爲了執行執行順序,你需要在你的線程之間實現一些信號。 看看Synchronization Primitives,具體來說,Auto/ManualResetEvent可能是你想要的。

2

編寫多線程代碼並不是一個好主意,該代碼假定或要求在不同線程上執行特定順序的執行。多線程的重點在於允許彼此獨立地執行獨立。獨立意味着不表示或暗示特定的順序。 CPU時間可能不會在兩個線程之間均勻分佈,例如,特別是一個線程正在等待外部信號事件,而另一個線程正在計算循環中。

對於您的特定代碼,在OnSimulationProgressEvent處理程序中設置IsResetCompleted = true;似乎很奇怪。復位活動的完成狀態應該由復位活動來設置,而不是在另一個線程中執行假設其他一些事件:「如果我們在這裏,在其他線程的工作必須完成。」

你應該檢查你的設計,並確定線程之間你的假設和依賴。如果線程B不能進行,直至後線程A已經完成的東西,你首先應該重新審視你爲什麼把這個工作在不同的線程,那麼也許使用同步對象(如的AutoResetEvent)的線程之間進行協調。

這裏的關鍵是,如果你把一個連續任務,它拆分成多個線程,但線程使用鎖或同步對象序列化它們的執行,再有就是使用多線程沒有好處。該操作仍然是順序的。

2

我不知道如果我理解這個問題完全,但如果您的要求很簡單,就是要防止SimulnProgress的身體XmlResetfn之前執行至少執行一次,你可以這樣做:

public readonly object lockThis = new object(); 
private readonly ManualResetEvent resetHandle = new ManualResetEvent(false); 

private void SimulnProgress() 
{ 
    resetHandle.WaitOne(); 

    lock (lockThis) 
    { 
     UIControlHandler.Instance.ShowSimulationProgress(); 
    } 
} 

private void XmlResetFn() 
{ 
    lock (lockThis) 
    { 
     DataStoreSingleTon.Instance.GetFPBConfigurationInstance().ResetXmlAfterCollision(); 
    } 

    resetHandle.Set(); 
}