启动线程,这类功能的逻辑?

时间:2012-05-16 15:48:13

标签: c# multithreading

我有一个逻辑问题我不知道如何解决..基本上我有一个基于numericUpDown值启动线程的程序,如果用户在numericUpDown框中选择5,则5个线程将​​启动。

问题是用户还有一个列表框,他们可以填写信息,这将在线程中使用..

所以我希望能够在循环中执行而不是从numericUpDown值循环5次if是;让我们说用户在listBox中输入10个项目,并选择使用5个线程..然后我想让所有的listBox项目排队,但一次只运行5个..

我将如何实现这一目标?

哦,如果这很重要,这就是我开始我的线程的方式:

                Thread thread = new Thread(() => doTask(numeret));
                thread.IsBackground = true;
                thread.Start();

3 个答案:

答案 0 :(得分:1)

我相信您希望使用ThreadPool,如下所述:

http://msdn.microsoft.com/en-us/library/system.threading.threadpool.aspx

您需要指定要使用的线程数,然后使用ThreadPool.QueueUserWorkItem对任务进行排队。

或者,您可以使用LinQ的并行扩展来执行异步任务(与多线程不同) - 并指定.MaxDegreesOfParalallism()值(仅设置最大上限)

itemsToProcess.AsParallel().MaxDegreesOfParalallism(numThreads).ForAll(item =>
{
    doTask(item);
});

答案 1 :(得分:0)

通常,这样的事情是使用工作线程完成的。您可以创建工作项列表(=列表框条目):

List<WorkItem> myWorkItems = ...; // contains 10 items

然后你创建你的线程。但是,您还没有为线程分配工作项(正如您在示例中所做的那样):

for (int i = 0; i < numberOfThreads; i++) {   // creates 5 threads
    var t = new Thread(doWork);
    t.IsBackground = true;
    t.Start();
}

每个线程都运行一个循环,检查新的工作项(线程安全!)并开始工作,直到不再需要做任何工作:

void doWork() {
    while (true) {
        WorkItem item;

        lock(someSharedLockObject) {
            if (myWorkItems.Count == 0)
                break; // no more work to be done
            item = myWorkItems[0];
            myWorkItems.Remove(item);
        }

        doTask(item);
    }
}

这类似于.net Framework的ThreadPool。但是,ThreadPool旨在在框架中选择线程数时能够最好地工作。上面的例子让你完全控制线程的数量(这似乎是你想要的)。

答案 2 :(得分:0)

将列表框中的信息存储在堆栈中(例如) 然后,在doTask()方法中:从堆栈中弹出一个元素,然后再做一遍,直到堆栈为空。

基本上:

//Stack containing the info to process
Stack<string> infos = new Stack<string>();

//Method for the thread
void doTask()
{
    while(true)
    {
        string info;
        //Threadsafe access to the stack
        lock (infos.SyncRoot)
        {
            //Exit the thread if no longer info to process
            if (infos.Count == 0) return;

            info = infos.Pop();
        }
        //Do the actual stuff on the info
        __DoStuff(info);
    }
}