ThreadPool.QueueUserWorkItem

把方法加到到线程中执行。线程池中有可用线程会被调用执行。

 static void Main(string[] args)
 {
     Console.WriteLine("begin:" + Thread.CurrentThread.ManagedThreadId);

     ThreadPool.QueueUserWorkItem(state =>
                                  {
                                      Console.WriteLine("test:" + Thread.CurrentThread.ManagedThreadId);
                                      Thread.Sleep(10000);
                                  });
     Console.WriteLine("end:" + Thread.CurrentThread.ManagedThreadId);

     Console.ReadLine();
 }

执行结果如下:

1595372389569

开五个循环测试

每个循环会开一个线程 。 一共五个线程 。

Console.WriteLine("begin:" + Thread.CurrentThread.ManagedThreadId);
for (int i = 0; i < 5; i++)
{
    ThreadPool.QueueUserWorkItem(state =>
                                 {
                                     Console.WriteLine("test:" + Thread.CurrentThread.ManagedThreadId);
                                     Thread.Sleep(10000);
                                 });
}

Console.WriteLine("end:" + Thread.CurrentThread.ManagedThreadId);

Console.ReadLine();

测试结果

除了主线程 ,开了五个线程 。

1595372713983

假如开100个。

线程用完销毁后会重新再利用。 线程 6,22,17 已经 开始被重复利用。

1595372836067

假如线程执行时间很长。没有到销毁时间

可以看到创建的线程不断增加, 内存也在不断的增加。每多开一个线程就浪费一点内存。这个内存理率上是1M,但内存每次显示增加100-200k左右。

1595373029699

线程内循环

如果是只开一个线程的话,需要循环的时候,把循环放到线程内

ThreadPool.QueueUserWorkItem(state =>
                             {
                                 for (int i = 0; i < 100; i++)
                                 {
                                     Console.WriteLine("test:" + Thread.CurrentThread.ManagedThreadId);
                                     Thread.Sleep(10000000);
                                 }
                             });

只开一个线程 ,在等,如果时间小,运行完接着用,都是在线程10内执行。

1595373301930

Parallel并行

直接并行会卡主线程

可以看到在paraller运行时, 主线程中的end没有执行,一直在等待paraller执行完

1595373559897

在线程内执行并行计算

这样的话,则不会卡主线程。

ThreadPool.QueueUserWorkItem(state => Parallel.ForEach(ls, x =>
                                                       {
                                                           Console.WriteLine("test:" + Thread.CurrentThread.ManagedThreadId);
                                                           Thread.Sleep(1000);
                                                       }));

1595373657192

ThreadPool也可以换成task

同样不会卡主线程 。

1595373831736

task等任务结束以后再继续执行

应用 于重复任务

private static void Main(string[] args)
        {
            Console.WriteLine("begin:" + Thread.CurrentThread.ManagedThreadId);
            int begin = 0;
            List<int> ls = new List<int>();

            for (int i = 0; i < 10; i++)
            {
                ls.Add(i);
            }
            Action action = () => Parallel.ForEach(ls, x =>
            {
                Console.WriteLine("test:" + Thread.CurrentThread.ManagedThreadId);
                Thread.Sleep(10000);
            });

            Task task = new Task(action);
            int output = 0;
            for (int j = 0; j < 100; j++)
            {
                Thread.Sleep(5000);

                if (begin == 0)
                {
                    begin++;
                    output++;
                    Console.WriteLine("当前执行第{0}次",output);
                    task.Start();
                }
                else
                {
                    if (task.IsCompleted)
                    {
                        task = new Task(action);
                        task.Start();
                        output++;
                        Console.WriteLine("当前执行第{0}次", output);
                    }
                    else
                    {
                        Console.WriteLine("之前的任务还没执行完");
                    }
                }

                Console.WriteLine("end:" + Thread.CurrentThread.ManagedThreadId);
            }
            Console.ReadLine();
        }
    }

1595492833950

关于Lock锁的使用。后面说下,先贴个图

1595900040818


本文由 hcb 创作,采用 知识共享署名 3.0,可自由转载、引用,但需署名作者且注明文章出处。

还不快抢沙发

添加新评论