线程安全的方式来填充/删除列表中的项目

时间:2013-06-02 12:25:53

标签: c# multithreading

我在C#Win应用程序中运行了2个辅助线程。

第一个线程读取Sql Server配置文件消息,并将其作为字符串添加到列表框中以形成一种队列。 另一个线程将逐个发送这些跟踪消息,并相应地从列表中删除它们。

现在我非常确定它会引起问题。任何方法可以确保只有一个线程能够访问这两个函数之一:

    void AddItemThreadSafe(string item)
    {
        this.Invoke((MethodInvoker)delegate
        {
            listBoxCollection.Items.Add(item);
        });
    }

    void RemoveItemThreadSafe()
    {
        this.Invoke((MethodInvoker)delegate
        {
            listBoxCollection.Items.RemoveAt(0);
        });
    }

3 个答案:

答案 0 :(得分:3)

通常,使用lock来同步对代码段的线程访问。

private static object listLocker = new object();

void AddItemThreadSafe(string item)
{
    this.Invoke((MethodInvoker)delegate
    {
        lock (listLocker)
        {
            listBoxCollection.Items.Add(item);
        }
    });
}

void RemoveItemThreadSafe()
{
    this.Invoke((MethodInvoker)delegate
    {
        lock (listLocker)
        {
            listBoxCollection.Items.RemoveAt(0);
        }
    });
}

在这种特殊情况下(如果我错了,有人纠正我),我相信你从同一个对象调用方法的事实已经同步了访问权限,使得锁多余。

答案 1 :(得分:2)

好消息是表单上的Invoke方法已经为您同步了。这就是Invoke的重点:对方法/委托进行排队,使其在创建表单的唯一UI线程上运行。

答案 2 :(得分:1)

使用内置Thread-Safe Collections 比如ConcurrentBag Class

从你的qustion Isaw你需要某种队列,所以使用ConcurrentQueue Class