c#多线程并发执行一个操作函数


有时候我们进行很多的数据对比运算时,单线程的程序显得很慢,这个时候可以用多线程并发运行:



  int maxThread = 10;  //10个并发线程
            int currTNum = 0;


            


            WaitHandle[] whs = new WaitHandle[maxThread];  //WaitHanle类MSDN上的定义: 封装了一些对象,这些对象等待着独占访问共享资源,这里相当于占用10个资源的意思


           
            for (int i = 0; i < whs.Length; i++)
            {
                whs[i] = new AutoResetEvent(false);   //AutoResetEvent是一个开关,设置为true时,whs占用资源对象就会自动启动. 设置为false时,只有进行 AutoResetEvent.set()之后才能启动
            }
            int sortIdx = 0;

//循环遍历一千个参数,对这1000个参数进行并发执行 Dotask()函数
             for (int i= 0;i<1000;i++)
                {


                    var ex = i;            


                  
                    currTNum++;  //线程数加一
                    if (currTNum >= maxThread)
                    {
                     //当前线程数大于或者等于最大线程数时 ,即10个线程数全部被占满,这时等待释放资源,把释放资源的线程编号给sortldx
                        int freeIdx = WaitHandle.WaitAny(whs); 
                        currTNum--;
                        sortIdx = freeIdx;
                    }
                    else
                    {
                //10个线程未占满时,依次给编号0到9
                        sortIdx = currTNum - 1;
                    }


                  


                  //线程池队列,依次执行线程
                        ThreadPool.QueueUserWorkItem(new WaitCallback((p) =>
                        {
                         
                          Dotask(p);  //要执行的函数,这里的p等于ex的内容
                            (whs[sortIdx] as AutoResetEvent).Set();
                        }), ex);   //唤醒线程


                    }

如果在for()循环外直接加  Messagebox.show("结束了"); 会发现 有时候已经弹出窗口了,但 仍有线程在运行。

这是因为for()循环虽然进行完了,但线程池中仍有线程在等待执行.


那我们什么时候才知道任务执行完了呢   这里我们要判断线程池中的线程是否执行完 执行完了 再弹出提示

int maxWorkerThreads, workerThreads;
                int portThreads;
                ThreadPool.GetMaxThreads(out maxWorkerThreads, out 


portThreads);
                ThreadPool.GetAvailableThreads(out workerThreads, out 


portThreads);
                if (maxWorkerThreads - workerThreads == 0)
                {
                 Messagebox.show("结束了");
                    break;
                }





你可能感兴趣的:(多线程,并发,线程池,C#)