C#线程锁失败

时间:2010-08-31 12:56:38

标签: c# multithreading

我有两个工作线程。我用同一个锁锁定了两个,但是threadB在threadA之前被执行了,所以异常来了。我用同一个锁对象锁定了两个。线程B正在使用委托函数。我怎么解决这个问题。

详细信息:


我有一个名为StateSimulation的班级。 里面有两个叫做的函数               a)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();
    }
}

请给出解决方案。 问候 Nidhin KR

3 个答案:

答案 0 :(得分:2)

锁定旨在防止多个线程同时进入给定的代码段。它们不是以任何其他方式同步线程,例如,使它们以某种特定顺序执行代码。

要强制执行命令,您需要在线程之间实现一些信号。 看看Synchronization Primitives,具体来说,Auto/ManualResetEvent可能就是你想要的。

答案 1 :(得分:2)

编写多线程代码并不是一个好主意,这些代码假设或要求在不同的线程上以特定顺序执行。多线程的全部意义在于允许事物彼此独立地执行。独立意味着没有明示或暗示特定顺序。 CPU时间可能不会在两个线程之间平均分配,例如,特别是一个线程正在等待外部信号事件而另一个线程处于计算循环中。

对于您的特定代码,在OnSimulationProgressEvent处理程序中设置IsResetCompleted = true;似乎很奇怪。 Reset活动的完成状态应该由Reset活动设置,而不是由在另一个线程中执行的其他事件设置,假设“如果我们在这里,则必须完成另一个线程中的工作。”

您应该检查您的设计并确定线程之间的假设和依赖关系。如果线程B必须在线程A完成之后才继续进行,那么首先应该重新检查为什么要将这项工作放在不同的线程中,然后使用同步对象(例如AutoResetEvent)来协调线程。

这里的关键点是,如果您执行顺序任务并将其拆分为多个线程,但线程使用锁定或同步对象来序列化其执行,那么使用多个线程没有任何好处。该操作仍然是连续的。

答案 2 :(得分: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();
}