如何确保一次只有一个线程可以访问集合类型的实例

时间:2012-01-06 23:47:51

标签: c# multithreading synchronization

我的代码(C#)中有几个地方会修改队列或列表。我想确保在任何时候只有一个线程修改队列或列表。那么如何在C#中保持一致性?谢谢

编辑 请参阅示例代码COMException on Main Thread of WPF application

5 个答案:

答案 0 :(得分:2)

访问或修改队列或列表时按住互斥锁。

答案 1 :(得分:2)

使用lock声明。

    lock(myObject) {

    //Code

    }

答案 2 :(得分:2)

System.Collections.Concurrent命名空间和框架中的其他位置有几种线程安全类型。使用这些可能是最简单的选择。

您还可以使用lock语句执行自己的显式锁定。 E.g。

public class Foo
{
    private readonly List<int> list = new List<int>();
    private readonly object locker = new object();

    public void SomeCommand(Bar bar)
    {
        lock (this.locker)
        {
            // do something here?
            this.list.Add(..);
            // do something here?
        }
    }

    public Baz SomeQuery()
    {
        lock (this.locker)
        {
            // do something here?
            this.list.Select(...);
            // do something here?
        }
    }

    public void SomethingElseEntirely()
    {
        lock (this.locker)
        {
            // do something here
        }            
    }
}

最佳选择因具体情况而异。例如。你想同步除了集合操作之外的其他操作(如代码示例中所示),你是否希望进行性能调整以获得更多读取而不是写入或更多写入而不是读取(某些内置类型已在这些中调整)方式)等等。

您还可以尝试使用其他显式线程同步类型,例如ReaderWriterLockSlim,它针对更多读取而不是写入进行了优化,并查看最适合您方案的内容。

答案 3 :(得分:2)

如果您使用的是.NET 3或更高版本,最简单的解决方案是使用SynchronizedCollection

答案 4 :(得分:1)

最好使用内置的线程安全集合,例如ConcurrentQueue