博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
多线程备忘
阅读量:4982 次
发布时间:2019-06-12

本文共 9162 字,大约阅读时间需要 30 分钟。

1.以前一直在用多线程,但对于多个线程完成一个任务时,如何汇合到主线程不太清楚,有时竟傻到去记录每个线程的状态来轮询等待(此处不讨论线程池),下面我写了一个例子,虽然和自己预想的结果有点出入,但确定实现了这个功能,就是Thread.Join方法,代码如下:

using System;using System.Collections.Generic;using System.Linq;using System.Text;using System.Threading;namespace MultiThreadTest{    class Program    {        static void Main(string[] args)        {            var thread1 = new Thread(new ThreadStart(ThreadProc1));            var thread2 = new Thread(new ThreadStart(ThreadProc2));            thread1.Start();            thread2.Start();                        thread1.Join();            thread2.Join();            Console.WriteLine("{0} All threads end.", DateTime.Now);            Console.ReadLine();        }        public static void ThreadProc1()        {            Console.WriteLine("{0} Thread 1 start.", DateTime.Now);            Thread.Sleep(5000);            Console.WriteLine("{0} Thread 1 end.", DateTime.Now);        }        public static void ThreadProc2()        {            Console.WriteLine("{0} Thread 2 start.", DateTime.Now);            Thread.Sleep(3000);            Console.WriteLine("{0} Thread 2 end.", DateTime.Now);        }    }}

输出结果如下:

2012-11-30 13:54:41 Thread 1 start.2012-11-30 13:54:41 Thread 2 start.2012-11-30 13:54:44 Thread 2 end.2012-11-30 13:54:46 Thread 1 end.2012-11-30 13:54:46 All threads end.  

 

2.用Child Task也可以实现这一效果:

using System;using System.Collections.Generic;using System.Linq;using System.Text;using System.Threading;using System.Threading.Tasks;namespace MultiThreadTest{    class Program    {        static void Main(string[] args)        {            var tasks = new Task(() =>             {                var task1 = new Task(ThreadProc1,TaskCreationOptions.AttachedToParent);                var task2 = new Task(ThreadProc2,TaskCreationOptions.AttachedToParent);                task1.Start();                task2.Start();            });            tasks.Start();            tasks.Wait();            Console.WriteLine("{0} All threads end.", DateTime.Now);            Console.ReadLine();        }        public static void ThreadProc1()        {            Console.WriteLine("{0} Thread 1 start.", DateTime.Now);            Thread.Sleep(5000);            Console.WriteLine("{0} Thread 1 end.", DateTime.Now);        }        public static void ThreadProc2()        {            Console.WriteLine("{0} Thread 2 start.", DateTime.Now);            Thread.Sleep(3000);            Console.WriteLine("{0} Thread 2 end.", DateTime.Now);        }    }}

输出结果如下:

2012-11-30 16:27:49 Thread 2 start.2012-11-30 16:27:49 Thread 1 start.2012-11-30 16:27:52 Thread 2 end.2012-11-30 16:27:54 Thread 1 end.2012-11-30 16:27:54 All threads end.

 

3.异步线程UI访问时会报错,可以使用委托通过this.invoke来访问:

如果没有参数传递:

   1)winform中可以这样访问

this.Invoke(new MethodInvoker(delegate() {       //code here              }));pictureBox1.Invoke((Action)delegate(){        pictureBox1.Update();});

如果有参数:

private delegate void SetResult(string result);SetResult delSetResult = setResult;this.Invoke(delSetResult, result); //this为UI线程对象

  2)WPF中可以这样访问

public delegate void MethodInvoker();this.Dispatcher.Invoke(new MethodInvoker(delegate(){     btnLogin.IsEnabled = true;}));

 

4.线程池使用示例。

using System;using System.Collections.Generic;using System.Linq;using System.Text;using System.Threading;using System.Diagnostics;namespace ConsoleApplication7{    class Program    {        private static Random rnd = new Random();        static void Main(string[] args)        {            var events = new List
(); for (var i = 0; i < 10; i++) { var resetEvent = new ManualResetEvent(false); ThreadPool.QueueUserWorkItem( arg => { doWork(arg); resetEvent.Set(); }, i); events.Add(resetEvent); } WaitHandle.WaitAll(events.ToArray()); Debug.Print("{0}\t All task Completed", DateTime.Now); } public static void doWork(object p) { var id = p.ToString(); var seconds = rnd.Next(1000, 10000); Thread.Sleep(seconds); Debug.Print("{0}\tTask [{1}] Completed", DateTime.Now, id); } }}

输出结果如下:

06/30/2018 10:42:25 Task [3] Completed

06/30/2018 10:42:28 Task [2] Completed
06/30/2018 10:42:29 Task [5] Completed
06/30/2018 10:42:30 Task [1] Completed
06/30/2018 10:42:32 Task [6] Completed
06/30/2018 10:42:32 Task [7] Completed
06/30/2018 10:42:32 Task [4] Completed
06/30/2018 10:42:33 Task [0] Completed
06/30/2018 10:42:34 Task [8] Completed
06/30/2018 10:42:35 Task [9] Completed
06/30/2018 10:42:35 All task Completed

 

 5. 多线程综合运用示例:

class Program    {        static void Main(string[] args)        {            demo4();            Console.ReadLine();        }        static void demo1()        {            ThreadPool.QueueUserWorkItem(new WaitCallback(delegate(object obj) {                for (var i = 0; i < 5; i++)                {                    Console.WriteLine("{0}\ti={1}", DateTime.Now, i);                    Thread.Sleep(10);                }            }));            ThreadPool.QueueUserWorkItem(new WaitCallback(delegate(object obj)            {                for (var j = 0; j < 5; j++)                {                    Console.WriteLine("{0}\tj={1}", DateTime.Now, j);                    Thread.Sleep(15);                }            }));            ThreadPool.QueueUserWorkItem(new WaitCallback(delegate(object obj)            {                for (var k = 0; k < 5; k++)                {                    Console.WriteLine("{0}\tk={1}", DateTime.Now, k);                    Thread.Sleep(13);                }            }));        }        static void demo2()        {            var t1 = new Task(new Action(delegate()            {                for (var i = 0; i < 5; i++)                {                    Console.WriteLine("{0}\ti={1}", DateTime.Now, i);                    Thread.Sleep(10);                }            }));            t1.Start();            var t2 = new Task(new Action(delegate()            {                for (var j = 0; j < 5; j++)                {                    Console.WriteLine("{0}\tj={1}", DateTime.Now, j);                    Thread.Sleep(15);                }            }));            t2.Start();            var t3 = new Task(new Action(delegate()            {                for (var k = 0; k < 5; k++)                {                    Console.WriteLine("{0}\tk={1}", DateTime.Now, k);                    Thread.Sleep(13);                }            }));            t3.Start();            t1.Wait();            t2.Wait();            t3.Wait();            Console.WriteLine("所有任务执行完成");        }        static void demo3()        {            //经测试,子任务必须在父任务内部实例化,否则无法实现任务进度联动            var tasks = new Task(() =>            {                new Task(() =>                {                    for (var i = 0; i < 5; i++)                    {                        Console.WriteLine("{0}\ti={1}", DateTime.Now, i);                        Thread.Sleep(10);                    }                }, TaskCreationOptions.AttachedToParent).Start();                new Task(() =>                {                    for (var j = 0; j < 5; j++)                    {                        Console.WriteLine("{0}\tj={1}", DateTime.Now, j);                        Thread.Sleep(15);                    }                }, TaskCreationOptions.AttachedToParent).Start();                new Task(() =>                {                    for (var k = 0; k < 5; k++)                    {                        Console.WriteLine("{0}\tk={1}", DateTime.Now, k);                        Thread.Sleep(13);                    }                }, TaskCreationOptions.AttachedToParent).Start();            });            tasks.Start();            //异步完成调用            tasks.ContinueWith(parentTask => { Console.WriteLine("所有任务执行完成1"); });            tasks.Wait();            //同步完成调用            Console.WriteLine("所有任务执行完成2");          }        static void demo4()        {            //i,j,k 的三个循环的调用也是随机的,不是按i,j,k的顺序            Parallel.Invoke(                () =>                {                    //此处的i的输出是并发的,不是从小到大顺序的                    Parallel.For(0, 5, i =>                    {                        Console.WriteLine("{0}\ti={1}", DateTime.Now, i);                        Thread.Sleep(10);                    });                },                () =>                {                    //此处的j的输出是并发的,不是从小到大顺序的                    Parallel.For(0, 5, j =>                    {                        Console.WriteLine("{0}\tj={1}", DateTime.Now, j);                        Thread.Sleep(15);                    });                },                () =>                 {                     //此处的k的输出是并发的,不是从小到大顺序的                    Parallel.For(0, 5, k =>                    {                        Console.WriteLine("{0}\tk={1}", DateTime.Now, k);                        Thread.Sleep(13);                    });                  }            );        }    }

 

转载于:https://www.cnblogs.com/nanfei/archive/2012/11/30/2796141.html

你可能感兴趣的文章
autofac使用笔记
查看>>
面试题1—选取同一个字符第一不重复的字符
查看>>
新一代网站群的分享
查看>>
台州 OJ 2676 Tree of Tree 树状 DP
查看>>
Linux 下安装 MATLAB
查看>>
react
查看>>
JQUERY1.9学习笔记 之基本过滤器(七) 语言选择器
查看>>
Computer Vision的尴尬 转载自 林达华
查看>>
尝试MVP模式
查看>>
可拖拽的ListBox
查看>>
queue
查看>>
cppgl:一个对现代OpenGL的C++封装
查看>>
FFmpeg—— Bitstream Filters 作用
查看>>
给标签a加图标
查看>>
Sql 四大排名函数(ROW_NUMBER、RANK、DENSE_RANK、NTILE)(转载)
查看>>
git使用
查看>>
jquery radio取值,checkbox取值,select取值,radio选中,checkbox选中,select选中,及其相关...
查看>>
错误状态码URL重定向
查看>>
离线安装mysql数据库
查看>>
利用R进行多元线性回归分析
查看>>