有谁知道如何使用两个线程逐个处理集合?

时间:2011-05-24 12:04:53

标签: c# .net mysql multithreading producer-consumer

我想逐个将集合的元素出列,然后将它们的值存储在MYSQL数据库中。

当第一个元素出队时我想启动一个线程来更新数据库,然后当第二个元素出队时我想开始另一个线程。

当第一个线程完成执行时,我想重用它来处理队列中的第三个元素。然后,在第二个线程完成执行后,我想重用它来处理队列中的第四个元素。我想继续这种方式,直到处理队列中的所有元素。

这些所有进程在1ms处理另一个线程。

有没有人知道如何使用两个线程逐个处理集合?

1 个答案:

答案 0 :(得分:2)

以您建议的方式解决此问题似乎很复杂且没有必要。基本上你已经映射出系统,其中一个线程处理具有偶数索引的集合中的所有项目,另一个处理具有奇数索引的所有项目。

但是,如果您的真正目标是使用两个线程处理队列,并且哪个线程处理哪个项无关紧要,这是使用ConcurrentQueue<T>类执行此操作的一种方法:

    // Queue of items to process
    static ConcurrentQueue<string> queue;

    // Random number generator to simulate time it takes to do work.
    static Random rnd = new Random();

    static void Main(string[] args)
    {
        // Items to process.
        List<string> names = new List<string>() { "Joe", "Bob", "Fred", "Jack", "Jill", 
            "Suzy", "Amy", "Alice", "Andy", "Bill", "Chuck" };

        // Demonstrates putting the items into a concurrent queue.
        queue = new ConcurrentQueue<string>(names);

        // Work threads
        Thread first = new Thread(AddToDatabase);
        Thread second = new Thread(AddToDatabase);

        // Start the work threads
        first.Start("First");
        second.Start("Second");
    }

    // Simulated work routine.
    static void AddToDatabase(object state)
    {
        string name;
        while (queue.TryDequeue(out name))
        {
            Console.WriteLine(string.Concat(state, ": Putting ", name, " in the database."));
            Thread.Sleep(rnd.Next(1000, 5000));
        }
    }

运行此代码会产生如下输出:

First: Putting Joe in the database.
Second: Putting Bob in the database.
Second: Putting Fred in the database.
First: Putting Jack in the database.
Second: Putting Jill in the database.
First: Putting Suzy in the database.
Second: Putting Amy in the database.
First: Putting Alice in the database.
Second: Putting Andy in the database.
First: Putting Bill in the database.
Second: Putting Chuck in the database.

正如你所看到的,两个线程都在队列中运行,通常是切换回第四个,但没有什么能保证它们能以任何特定的顺序执行。

然而,即使这段代码也比你真正需要做的更多。您可以使用并行LINQ并让框架决定您需要多少线程:

// Items to process.
List<string> names = new List<string>() { 
    "Joe", "Bob", "Fred", "Jack", "Jill", "Suzy", "Amy", "Alice", 
    "Andy", "Bill", "Chuck" };

// Process using Parallel LINQ
names.AsParallel().ForAll(name =>
{
    var id = Thread.CurrentThread.ManagedThreadId;
    Console.WriteLine(string.Concat(id, ": Putting ", name, " in the database."));
    Thread.Sleep(rnd.Next(1000, 5000));
});

产生类似的输出:

1: Putting Amy in the database.
3: Putting Joe in the database.
1: Putting Alice in the database.
1: Putting Andy in the database.
3: Putting Bob in the database.
3: Putting Fred in the database.
1: Putting Bill in the database.
3: Putting Jack in the database.
1: Putting Chuck in the database.
3: Putting Jill in the database.
3: Putting Suzy in the database.

我遗漏了实际将项目放入数据库的代码部分。这是一个单独的问题,如何使用多个线程处理您的集合。如果您想了解有关ConcurrentQueue<T>等课程的信息,请查看Jon Skeet的article on multi-threading in .NET.