0

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

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

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

我将如何做到这一点?

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

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

3 回答 3

1

我相信您希望使用 a ThreadPool,如此处所述:

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

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

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

itemsToProcess.AsParallel().MaxDegreesOfParalallism(numThreads).ForAll(item =>
{
    doTask(item);
});
于 2012-05-16T15:59:08.933 回答
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 框架的ThreadPool所做的。然而,ThreadPool 被设计为在可以选择线程数作为框架时工作得最好。上面的示例使您可以完全控制线程数(这似乎是您想要的)。

于 2012-05-16T15:58:28.047 回答
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);
    }
}
于 2012-05-16T16:08:17.080 回答