使用C#的线程池问题

舍达尔

我正在做我的大学项目。使用的主要要求之一multithreading(用户可以选择线程号)。

我是C#的新手,基于互联网研究。我选择ThreadPool

我花了很多时间观察线程在VS中使用并行监视的行为,我不知道这是如何工作的。例如,threadNumber = 10但是并行监视仅显示4个激活的线程。

这是我的代码:

public void calculateBeta()
    {
        var finished = new CountdownEvent(1);
        for (int i = 0; i < threadNumber; i++)
        {
            finished.AddCount();
            ThreadPool.QueueUserWorkItem(
            (state) =>
            {
                try
                {
                   doSth();
                }
                finally
                {
                    finished.Signal();
                }
            });
        }
        finished.Signal();
        finished.Wait();
    }

我究竟做错了什么?我尝试使用许多不同的线程号值测试此代码,但该代码无法正常工作。

编辑:

 private void myTask(object index)
    {

            int z = (int)index;
            double[] result = countBeta(createTableB(z), createTableDiagonalA(z));
            int counter = 0;
            if ((rest != 0) && (z == threadNumber - 1))
            {
                for (int j = z * numbersInRow; j < (z + 1) * numbersInRow + rest; j++)
                {
                    N[j] = result[counter];
                    counter++;
                }
            }
            else
            {
                for (int j = z * numbersInRow; j < (z + 1) * numbersInRow; j++)
                {
                    N[j] = result[counter];
                    counter++;
                }
            }
            threads[z] = true;
    }


public void calculateBeta()
    {
        N = new double[num];
        setThreadNumber(2);
        checkThreadNumber();
        setNumberInRow();
        setRest();
        threads = new bool[threadNumber];
        for (int i = 0; i < threadNumber; i++)
        {
            Thread thread = new Thread(this.myTask);
            thread.IsBackground = true;
            thread.Start(i);
        }
        while (!checkThreads())
        {
        }
    }

private bool checkThread()
    {
        bool result = true;
        for (int i = 0; i < threads.Length; i++)
        {
            if (!threads[i])
                result = false;
        }

        return result;
    }

static void Main(string[] args)
    {


        Jacobi jacobi = new Jacobi();
        Console.WriteLine("Metoda Jacobiego");
        Console.WriteLine("Rozwiazywanie ukladu n-rownan z n-niewiadomymi Ax=b");
        jacobi.getNum();
        jacobi.getA();
        jacobi.getB();
        jacobi.calculateBeta();
        jacobi.calculateM();
        jacobi.calculateX();
        jacobi.countNorms();
        Console.ReadLine();
    }

我需要来自calculateBeta的结果才能进行进一步的计算。有时线程还没有完成,但是程序前进了而没有线程需要提供的数据。我现在正在使用bool变量,但是这种解决方案不是一种很好的解决方案(创建bool表,检查是否所有线程都已完成)如何用不同的方式进行管理?

保罗·萨西克|

这是因为您正在使用ThreadPool来管理线程。它将基于许多因素创建一定数量的线程。您可以调整一些设置,但是总体上来说,当您承诺使用ThreadPool管理线程时,您将提交到黑盒。请查看GetMaxThreadsGetMinThreads以及与它们对应的setter方法,以了解一些选项。

在MSDN上查看此ThreadPool体系结构文章它为班级的方式和原因提供了良好的背景。但是在介绍性段落中,您将看到以下句子,这是您遇到难题的关键:

线程池主要用于减少应用程序线程的数量并提供对工作线程的管理。

如果要控制在快速连续启动10个线程的位置,则应避免使用ThreadPool并自己管理线程。这是一个简单的,绝对最小的示例,它启动了十个线程,并且还向每个线程传递不同的数据,在本例中为索引:

void ButtonClickHandlerOrSomeOtherMethod()  
{
    for (int i=1; i<=10; i++) // using a 1-based index
    {
        new Thread(ThreadTask).Start(i);
    }
}

void ThreadTask(object i) 
{
    Console.WriteLine("Thread " + i + " ID: " + Thread.CurrentThread.ManagedThreadId);
}

和一些示例输出:

线程1 ID:19
线程2 ID:34
线程3 ID:26
线程4的ID:5
线程5 ID:36
线程6 ID:18
线程7 ID:9
线程8 ID:38
线程9 ID:39
线程10 ID:40

后续代码演示与线程同步并“等待”,直到它们全部完成:

void ButtonClickHandlerOrSomeOtherMethod() 
{
    // need a collection of threads to call Join after Start(s)
    var threads = new List<Thread>();

    // create threads, add to List and start them
    for (int i=1; i<=10; i++) {
        var thread = new Thread(ThreadTask);
        threads.Add(thread);
        // a background thread will allow main app to exit even
        // if the thread is still running
        thread.IsBackground = true;
        thread.Start(i);
    }

    // call Join on each thread which makes this thread wait on
    // all 10 other threads
    foreach (var thread in threads) 
        thread.Join();

    // this message will not show until all threads are finished
    Console.WriteLine("All threads finished.");
}

void ThreadTask(object i) 
{
    Console.WriteLine("Thread " + i + " ID: " + Thread.CurrentThread.ManagedThreadId);
    // introducing some randomness to how long a task "works on something"
    Thread.Sleep(100 * new Random().Next(0, 10));
    Console.WriteLine("Thread " + i + " finished.");
}

本文收集自互联网,转载请注明来源。

如有侵权,请联系[email protected] 删除。

编辑于
0

我来说两句

0条评论
登录后参与评论

相关文章

来自分类Dev

C ++中的Docker线程池端口问题

来自分类Dev

C#异步等待和线程池

来自分类Dev

C#异步等待和线程池

来自分类Dev

在C#中使用数组进行线程池化,索引超出范围

来自分类Dev

C#锁定线程问题

来自分类Dev

C#中的线程问题

来自分类Dev

异步使用线程池?

来自分类Dev

我对C#线程池的理解正确吗?

来自分类Dev

C#多线程:计算器池

来自分类Dev

线程池和对象的线程问题

来自分类Dev

如何在C ++中使用boost创建线程池?

来自分类Dev

使用C ++线程池库(CTPL)的异常错误

来自分类Dev

C#任务线程池-仅在10个线程上运行100个任务

来自分类Dev

c#控制线程池。同时运行的线程数量超过预期

来自分类Dev

C ++ 11动态线程池

来自分类Dev

使用 Executor Framrwork 的线程池

来自分类Dev

Java线程池任务超时问题

来自分类Dev

C#多线程问题,正在等待线程

来自分类Dev

C ++:线程池比单线程慢?

来自分类Dev

线程池未按预期使用线程?

来自分类Dev

具有固定线程池和大量任务的线程问题

来自分类Dev

C线程池-传递参数重复

来自分类Dev

C线程池-传递参数重复

来自分类Dev

C ++中的线程池 - 如何结束程序

来自分类Dev

使用聚合器时了解线程池

来自分类Dev

使用Boost :: thread类的线程池实现

来自分类Dev

在我的情况下使用线程池

来自分类Dev

C#异步等待池

来自分类Dev

使用Task类的C#多线程