c#线程同步问题

时间:2011-09-01 22:47:22

标签: c# multithreading synchronization

所以我看到 有趣的 玩线程的东西。

我有一个方法可以启动2个线程并继续其生命,我尝试执行以下操作以保证安全。

    bool CopyOk1 = false;
    bool CopyOk2 = false;
    new Thread(() => FirstMethod(tempList1, ref CopyOk1)).Start();
    new Thread(() => SecondMethod(tempList2, ref CopyOk2)).Start();
    var spinner = new SpinWait();
    while (!CopyOk1 || !CopyOk2)
        spinner.SpinOnce();

然后在两种方法中我都从以下

开始
    private static void FirstMethod(List<T> templist, ref bool CopyOk)
    {
        var temp = new T[templist.Count];
        templist.CopyTo(temp);
        CopyOk = true;
        //moves on
    }

我的目的是复制传递的列表,以便我可以在线程内安全地更改和使用它,以解除对调用者线程的阻塞。

我的问题是,在第二种方法不可预测的情况下,在数组初始化和列表CopyTo之间,基本列表以某种方式由某种东西改变。

这些列表是在调用者线程内创建的,并且在线程启动后实际上没有使用,所以我绝对 想法如何/为什么会发生这种情况。

毫无疑问,我在这里做错了什么,但我的诺言技巧不会让我看到,任何帮助都会受到赞赏。

4 个答案:

答案 0 :(得分:2)

使用全局锁定而不是锁定'templist'。然后使用相同的锁保护修改源列表的所有代码。

另外,也许是一边,但等待线程部分完成可以更优雅地完成,即不涉及循环。使用ManualResetEvent将允许原始线程等待在其他线程中发生“某事”。使用WaitOne将阻塞线程,直到在另一个线程中调用Set()。

private object m_Lock = new object();
private ManualResetEvent m_ResetOne = new ManualResetEvent(false);
private ManualResetEvent m_ResetTwo = new ManualResetEvent(false);

(...)

new Thread(() => FirstMethod(tempList1)).Start();
new Thread(() => SecondMethod(tempList2)).Start();
m_ResetOne.WaitOne();
m_ResetTwo.WaitOne();

(...)

private void FirstMethod(List<T> templist)
{
    lock (m_Lock)
    {
        var temp = new T[templist.Count];
        templist.CopyTo(temp);
    }
    m_ResetOne .Set();
    //moves on
}

答案 1 :(得分:1)

您发布的代码中没有任何内容表明您做错了什么。问题必须放在其他地方 - 正如评论者所建议的那样,在填充List1 / List2的代码中。如果您正在进行线程处理,也许您还没有等待该线程在继续之前完成填充列表?

答案 2 :(得分:0)

尝试此操作并检查行为

private static void FirstMethod(List<T> templist, ref bool CopyOk)
{
    T[] temp;

    lock (templist)
    {
        temp = new T[templist.Count];
        templist.CopyTo(temp);
    }
    CopyOk = true;
    //moves on
}

答案 3 :(得分:0)

您需要某种类型的同步机制来阻止List<T>被更改。我们在当前样本中看不到足够的代码以保证它不会被更改。

相关问题