那么四线程正是包涵有除了主线程之外的别样线程,那么多线程便是足以同时施行多少个职分

一、进度、线程及多线程的定义

一、进度、线程及八线程的定义

如何是八线程呢?不晓得。

何以是三十二线程呢?不清楚。

那什么是线程呢?聊到线程就不得不说说经过。小编在网上查找也招来了1部分材质,大多数所说的长河实际是很虚幻的东西。通俗的来讲,进度正是八个应用程序起始运维,那么那一个应用程序就会存在二个属于这几个应用程序的经过。

那怎么是线程呢?提及线程就只好说说经过。小编在网上检索也查找了壹些素材,大多数所说的进度实际是很空洞的东西。通俗的来讲,进度就是三个应用程序起初运维,那么这一个应用程序就会设有七个属于这些应用程序的经过。

那正是说线程就是经过中的基本进行单元,每一种进度中都至少存在着二个线程,那些线程是依据进程创立而创办的,所以这些线程我们称为主线程。那么三十二线程正是富含有除了主线程之外的别样线程。要是一个线程能够进行2个职务,那么八线程正是足以同时实施四个职责。

那便是说线程正是经过中的基本举行单元,各样进度中都至少存在着一个线程,那一个线程是依据进程创设而创设的,所以这一个线程我们称为主线程。那么10二线程就是富含有除了主线程之外的别样线程。假如2个线程能够进行2个职责,那么二10102线程正是足以同时实施多少个任务。

以上的定义纯属个人知道,如有何窘迫的地点,还请多多指正。

上述的定义纯属个人知道,如有啥狼狈的地点,还请多多指正。

 

 

贰、线程的基本知识

2、线程的基本知识

Thread 类

Thread 类

Thread 类是用来控制线程的基本功类,它存在于 System.Threading
命名空间。通过 Thread
可以操纵当前选用程序域中线程的制造、挂起、结束、销毁。

Thread 类是用来控制线程的底子类,它存在于 System.Threading
命名空间。通过 Thread
能够操纵当前应用程序域中线程的创立、挂起、截止、销毁。

Thread 壹些常用属性:

Thread 一些常用属性:

威尼斯人娱乐 1

威尼斯人娱乐 2

Thread 一些常用方法:

Thread 1些常用方法:

威尼斯人娱乐 3

威尼斯人娱乐 4

Thread 的先期级:

Thread 的事先级:

威尼斯人娱乐 5

威尼斯人娱乐 6

 

 

3、10贰线程的简练示例

三、十二线程的简约示例

上面就从简单的多线程早先理解吧,那里作者成立了多少个控制台应用程序。

下边就从简单的二十四线程开始驾驭啊,这里笔者成立了3个控制台应用程序。

   class Program
    {
        static void Main(string[] args)
        {
            ThreadDemoClass demoClass = new ThreadDemoClass();

            //创建一个新的线程
            Thread thread = new Thread(demoClass.Run);

            //设置为后台线程
            thread.IsBackground = true;

            //开始线程
            thread.Start();

            Console.WriteLine("Main thread working...");
            Console.WriteLine("Main thread ID is:" + Thread.CurrentThread.ManagedThreadId.ToString());

            Console.ReadKey();
        }
    }

    public class ThreadDemoClass
    {
        public void Run()
        {
            Console.WriteLine("Child thread working...");
            Console.WriteLine("Child thread ID is:" + Thread.CurrentThread.ManagedThreadId.ToString());
        }
    }
   class Program
    {
        static void Main(string[] args)
        {
            ThreadDemoClass demoClass = new ThreadDemoClass();

            //创建一个新的线程
            Thread thread = new Thread(demoClass.Run);

            //设置为后台线程
            thread.IsBackground = true;

            //开始线程
            thread.Start();

            Console.WriteLine("Main thread working...");
            Console.WriteLine("Main thread ID is:" + Thread.CurrentThread.ManagedThreadId.ToString());

            Console.ReadKey();
        }
    }

    public class ThreadDemoClass
    {
        public void Run()
        {
            Console.WriteLine("Child thread working...");
            Console.WriteLine("Child thread ID is:" + Thread.CurrentThread.ManagedThreadId.ToString());
        }
    }

创制一个新的线程还足以行使 ThreadStart 委托的形式。如下:

开创三个新的线程还足以应用 ThreadStart 委托的点子。如下:

//创建一个委托,并把要执行的方法作为参数传递给这个委托
ThreadStart threadStart = new ThreadStart(demoClass.Run);
Thread thread = new Thread(threadStart);
//创建一个委托,并把要执行的方法作为参数传递给这个委托
ThreadStart threadStart = new ThreadStart(demoClass.Run);
Thread thread = new Thread(threadStart);

实践结果:

举行理并了结果:

威尼斯人娱乐 7

威尼斯人娱乐 8

依照上述的结果大家能够分析得到,主线程创制了3个子线程并运营了它,可是主线程未有等到子线程执行到位,而是继续再往下执行的。

依据以上的结果大家得以分析获得,主线程创设了二个子线程并运营了它,然则主线程未有等到子线程执行到位,而是继续再往下实施的。

那就提到到了线程异步或联合的难点了,这几个大家前面再说。

那就关乎到了线程异步或联手的题材了,这一个大家后边再说。

接轨上边包车型地铁标题,那么只要小编想要等到子线程执行到位未来再持续主线程的办事呢(当然,小编以为一般不会有那种须求)。

持续下面的难题,那么一旦本人想要等到子线程执行到位之后再持续主线程的办事啊(当然,小编认为一般不会有这种须要)。

咱俩得以采取 Join() 那个主意,修改以往的代码:

笔者们得以选择 Join() 这么些方式,修改之后的代码:

   class Program
    {
        static void Main(string[] args)
        {
            ThreadDemoClass demoClass = new ThreadDemoClass();

            //创建一个新的线程
            Thread thread = new Thread(demoClass.Run);

            //设置为后台线程
            thread.IsBackground = true;

            //开始线程
            thread.Start();

            //等待直到线程完成
            thread.Join();

            Console.WriteLine("Main thread working...");
            Console.WriteLine("Main thread ID is:" + Thread.CurrentThread.ManagedThreadId.ToString());

            Console.ReadKey();
        }
    }

    public class ThreadDemoClass
    {
        public void Run()
        {
            Console.WriteLine("Child thread working...");
            Console.WriteLine("Child thread ID is:" + Thread.CurrentThread.ManagedThreadId.ToString());
        }
    }
   class Program
    {
        static void Main(string[] args)
        {
            ThreadDemoClass demoClass = new ThreadDemoClass();

            //创建一个新的线程
            Thread thread = new Thread(demoClass.Run);

            //设置为后台线程
            thread.IsBackground = true;

            //开始线程
            thread.Start();

            //等待直到线程完成
            thread.Join();

            Console.WriteLine("Main thread working...");
            Console.WriteLine("Main thread ID is:" + Thread.CurrentThread.ManagedThreadId.ToString());

            Console.ReadKey();
        }
    }

    public class ThreadDemoClass
    {
        public void Run()
        {
            Console.WriteLine("Child thread working...");
            Console.WriteLine("Child thread ID is:" + Thread.CurrentThread.ManagedThreadId.ToString());
        }
    }

推行结果:

执行结果:

威尼斯人娱乐 9

威尼斯人娱乐 10

上面的代码相比从前就添加了一句
thread.Join(),它的效劳便是用来阻塞后边的线程,直到当前线程完结之后。当然,还有此外的点子能够形成,比如大家明天把
thread.Join() 换到

位置的代码相比较在此之前就添加了一句
thread.Join(),它的功能正是用来阻塞前面包车型地铁线程,直到近期线程达成未来。当然,还有别的的法子能够做到,比如我们明天把
thread.Join() 换到

上边那句代码。

下边那句代码。

//挂起当前线程指定的时间
Thread.Sleep(100);
//挂起当前线程指定的时间
Thread.Sleep(100);

就当前的气象来说,这样实在能够满意供给,可是那样做有多个弊端,正是,当子线程所实施的点子逻辑相比复杂耗费时间较长的时候,那样的点子就不必然能够,即便能够修改线程挂起的时光,不过这几个执行的时光却是不定的。所以,Thread.Sleep()
方法壹般用来安装二1010贰线程之间进行的间隔时间的。

就现阶段的场馆来说,那样确实能够满意急需,可是如此做有几个弊病,正是,当子线程所推行的诀窍逻辑相比复杂耗费时间较长的时候,那样的章程就不自然能够,即便能够修改线程挂起的大运,可是那个执行的年月却是不定的。所以,Thread.Sleep()
方法壹般用来设置拾2线程之间举办的间隔时间的。

其它,Join()
方法也承受2个参数,该参数用于内定阻塞线程的时光,借使在钦定的年华内该线程未有终止,那么就回去
false,假若在钦赐的小运内已告1段落,那么就赶回 true。

别的,Join()
方法也承受一个参数,该参数用于钦点阻塞线程的日子,要是在钦定的光阴内该线程没有停歇,那么就返回false,假如在钦点的时光内已告一段落,那么就回去 true。

 

 

下面的那种应用十2线程的方法只是简约的出口壹段内容而已,多数情形下我们必要对线程调用的办法传入参数和接收再次回到值的,可是上边那种方法是不接受参数并且未有重临值的,那么大家得以行使 ParameterizedThreadStart
委托来创建三十二线程,这些委托还可以一个 object
类型的参数,大家能够在那地点做小说。

地点的那种使用多线程的点子只是大约的输出一段内容而已,多数景观下我们供给对线程调用的章程传入参数和接收再次回到值的,可是下面这种方法是不收受参数并且未有再次来到值的,那么我们能够运用 ParameterizedThreadStart
委托来成立十2线程,那些委托还可以2个 object
类型的参数,大家得以在那上面做小说。

   class Program
    {static void Main(string[] args)
        {
            ThreadDemoClass demoClass = new ThreadDemoClass();

            //创建一个委托,并把要执行的方法作为参数传递给这个委托
            ParameterizedThreadStart threadStart = new ParameterizedThreadStart(demoClass.Run);

            //创建一个新的线程
            Thread thread = new Thread(threadStart);

            //开始线程,并传入参数
            thread.Start("Brambling");

            Console.WriteLine("Main thread working...");
            Console.WriteLine("Main thread ID is:" + Thread.CurrentThread.ManagedThreadId.ToString());
            Console.ReadKey();
        }
    }

    public class ThreadDemoClass
    {
        public void Run(object obj)
        {
            string name = obj as string;

            Console.WriteLine("Child thread working...");
            Console.WriteLine("My name is " + name);
            Console.WriteLine("Child thread ID is:" + Thread.CurrentThread.ManagedThreadId.ToString());
        }
    }
   class Program
    {static void Main(string[] args)
        {
            ThreadDemoClass demoClass = new ThreadDemoClass();

            //创建一个委托,并把要执行的方法作为参数传递给这个委托
            ParameterizedThreadStart threadStart = new ParameterizedThreadStart(demoClass.Run);

            //创建一个新的线程
            Thread thread = new Thread(threadStart);

            //开始线程,并传入参数
            thread.Start("Brambling");

            Console.WriteLine("Main thread working...");
            Console.WriteLine("Main thread ID is:" + Thread.CurrentThread.ManagedThreadId.ToString());
            Console.ReadKey();
        }
    }

    public class ThreadDemoClass
    {
        public void Run(object obj)
        {
            string name = obj as string;

            Console.WriteLine("Child thread working...");
            Console.WriteLine("My name is " + name);
            Console.WriteLine("Child thread ID is:" + Thread.CurrentThread.ManagedThreadId.ToString());
        }
    }

推行结果:

执行结果:

威尼斯人娱乐 11

威尼斯人娱乐 12

PS:那里自个儿未曾加那句代码了(thread.IsBackground =
true,即把如今线程设置为后台线程),因为使用 thread.Start()
运转的线程私下认可为前台线程。那么前台线程和后台线程有啥不一样吗?

PS:那里本人未曾加这句代码了(thread.IsBackground =
true,即把当下线程设置为后台线程),因为使用 thread.Start()
运维的线程暗许为前台线程。那么前台线程和后台线程有怎么着界别吧?

前台线程就是系统会等待全数的前台线程运营甘休后,应用程序域才会自行卸载。而设置为后台线程之后,应用程序域会在主线程执行到位时被卸载,而不会等待异步线程的实施到位。

前台线程就是系统会等待全体的前台线程运行停止后,应用程序域才会活动卸载。而设置为后台线程之后,应用程序域会在主线程执行到位时被卸载,而不会等待异步线程的实践到位。

那正是说地点的结果能够看看在八线程完结了参数的传递,不过它也唯有贰个参数呢。不过它接受的参数是
object
类型的(万类之源),也等于说既能够是值类型或引用类型,也能够是自定义类型。(当然,自定义类型其实也是属于引用类型的)上面大家选取自定义类型作为参数字传送递。

那正是说地点的结果能够看到在多线程实现了参数的传递,不过它也唯有几个参数呢。可是它接受的参数是
object
类型的(万类之源),也正是说既能够是值类型或引用类型,也能够是自定义类型。(当然,自定义类型其实也是属于引用类型的)上边大家选用自定义类型作为参数传递。

   class Program
    {
        static void Main(string[] args)
        {
            ThreadDemoClass demoClass = new ThreadDemoClass();

            //创建一个委托,并把要执行的方法作为参数传递给这个委托
            ParameterizedThreadStart threadStart = new ParameterizedThreadStart(demoClass.Run);

            //创建一个新的线程
            Thread thread = new Thread(threadStart);

            UserInfo userInfo = new UserInfo();
            userInfo.Name = "Brambling";
            userInfo.Age = 333;

            //开始线程,并传入参数
            thread.Start(userInfo);

            Console.WriteLine("Main thread working...");
            Console.WriteLine("Main thread ID is:" + Thread.CurrentThread.ManagedThreadId.ToString());
            Console.ReadKey();
        }
    }

    public class ThreadDemoClass
    {
        public void Run(object obj)
        {
            UserInfo userInfo = (UserInfo)obj;

            Console.WriteLine("Child thread working...");
            Console.WriteLine("My name is " + userInfo.Name);
            Console.WriteLine("I'm " + userInfo.Age + " years old this year");
            Console.WriteLine("Child thread ID is:" + Thread.CurrentThread.ManagedThreadId.ToString());
        }
    }

    public class UserInfo
    {
        public string Name { get; set; }

        public int Age { get; set; }
    }
   class Program
    {
        static void Main(string[] args)
        {
            ThreadDemoClass demoClass = new ThreadDemoClass();

            //创建一个委托,并把要执行的方法作为参数传递给这个委托
            ParameterizedThreadStart threadStart = new ParameterizedThreadStart(demoClass.Run);

            //创建一个新的线程
            Thread thread = new Thread(threadStart);

            UserInfo userInfo = new UserInfo();
            userInfo.Name = "Brambling";
            userInfo.Age = 333;

            //开始线程,并传入参数
            thread.Start(userInfo);

            Console.WriteLine("Main thread working...");
            Console.WriteLine("Main thread ID is:" + Thread.CurrentThread.ManagedThreadId.ToString());
            Console.ReadKey();
        }
    }

    public class ThreadDemoClass
    {
        public void Run(object obj)
        {
            UserInfo userInfo = (UserInfo)obj;

            Console.WriteLine("Child thread working...");
            Console.WriteLine("My name is " + userInfo.Name);
            Console.WriteLine("I'm " + userInfo.Age + " years old this year");
            Console.WriteLine("Child thread ID is:" + Thread.CurrentThread.ManagedThreadId.ToString());
        }
    }

    public class UserInfo
    {
        public string Name { get; set; }

        public int Age { get; set; }
    }

施行结果:

实践结果:

威尼斯人娱乐 13

威尼斯人娱乐 14

利用自定义类型作为参数字传送递,理论上更七个参数也都以足以实现的。

动用自定义类型作为参数字传送递,理论上更三个参数也都以足以达成的。

 

 

四、线程池

四、线程池

使用 ThreadStart 和 ParameterizedThreadStart
创立线程如故相比不难的,可是出于线程的创制和销毁要求消耗一定的花费,过多的利用线程反而会促成内部存储器财富的荒废,从而影响属性,出于对质量的设想,于是引进了线程池的概念。线程池并不是在
CL汉兰达伊始化的时候立刻创制线程的,而是在应用程序要成立线程来推行职责的时候,线程池才会初步化三个线程,初阶化的线程和其他线程1样,可是在线程完结职务之后不会自行销毁,而是以挂起的情事回到线程池。当应用程序再次向现成池发出请求的时候,线程池里挂起的线程会再次激活执行职务。那样做能够减去线程成立和销毁所推动的付出。线程池建立的线程暗中认可为后台线程

应用 ThreadStart 和 ParameterizedThreadStart
创设线程还是相比较不难的,可是由于线程的创办和销毁必要消耗一定的开销,过多的选择线程反而会导致内部存款和储蓄器财富的浪费,从而影响属性,出于对质量的思量,于是引进了线程池的定义。线程池并不是在
CLKoleos初始化的时候立刻创造线程的,而是在应用程序要成立线程来执行任务的时候,线程池才会开始化3个线程,开始化的线程和其余线程1样,不过在线程完毕职务之后不会活动销毁,而是以挂起的情况回到线程池。当应用程序再度向现成池发出请求的时候,线程池里挂起的线程会再一次激活执行使命。那样做能够减掉线程创制和销毁所拉动的开支。线程池建立的线程暗中认可为后台线程

   class Program
    {
        static void Main(string[] args)
        {
            ThreadDemoClass demoClass = new ThreadDemoClass();

            //设置当没有请求时线程池维护的空闲线程数
            //第一个参数为辅助线程数
            //第二个参数为异步 I/O 线程数
            ThreadPool.SetMinThreads(5, 5);

            //设置同时处于活动状态的线程池的线程数,所有大于次数目的请求将保持排队状态,直到线程池变为可用
            //第一个参数为辅助线程数
            //第二个参数为异步 I/O 线程数
            ThreadPool.SetMaxThreads(100, 100);

            //使用委托绑定线程池要执行的方法(无参数)
            WaitCallback waitCallback1 = new WaitCallback(demoClass.Run1);
            //将方法排入队列,在线程池变为可用时执行
            ThreadPool.QueueUserWorkItem(waitCallback1);


            //使用委托绑定线程池要执行的方法(有参数)
            WaitCallback waitCallback2 = new WaitCallback(demoClass.Run1);
            //将方法排入队列,在线程池变为可用时执行
            ThreadPool.QueueUserWorkItem(waitCallback2,"Brambling");


            UserInfo userInfo = new UserInfo();
            userInfo.Name = "Brambling";
            userInfo.Age = 33;

            //使用委托绑定线程池要执行的方法(有参数,自定义类型的参数)
            WaitCallback waitCallback3 = new WaitCallback(demoClass.Run2);
            //将方法排入队列,在线程池变为可用时执行
            ThreadPool.QueueUserWorkItem(waitCallback3, userInfo);

            Console.WriteLine();
            Console.WriteLine("Main thread working...");
            Console.WriteLine("Main thread ID is:" + Thread.CurrentThread.ManagedThreadId.ToString());
            Console.ReadKey();
        }
    }

    public class ThreadDemoClass
    {
        public void Run1(object obj)
        {
            string name = obj as string;

            Console.WriteLine();
            Console.WriteLine("Child thread working...");
            Console.WriteLine("My name is " + name);
            Console.WriteLine("Child thread ID is:" + Thread.CurrentThread.ManagedThreadId.ToString());
        }

        public void Run2(object obj)
        {
            UserInfo userInfo=(UserInfo)obj;

            Console.WriteLine();
            Console.WriteLine("Child thread working...");
            Console.WriteLine("My name is " + userInfo.Name);
            Console.WriteLine("I'm " + userInfo.Age + " years old this year");
            Console.WriteLine("Child thread ID is:" + Thread.CurrentThread.ManagedThreadId.ToString());
        }
    }

    public class UserInfo
    {
        public string Name { get; set; }

        public int Age { get; set; }
    }
   class Program
    {
        static void Main(string[] args)
        {
            ThreadDemoClass demoClass = new ThreadDemoClass();

            //设置当没有请求时线程池维护的空闲线程数
            //第一个参数为辅助线程数
            //第二个参数为异步 I/O 线程数
            ThreadPool.SetMinThreads(5, 5);

            //设置同时处于活动状态的线程池的线程数,所有大于次数目的请求将保持排队状态,直到线程池变为可用
            //第一个参数为辅助线程数
            //第二个参数为异步 I/O 线程数
            ThreadPool.SetMaxThreads(100, 100);

            //使用委托绑定线程池要执行的方法(无参数)
            WaitCallback waitCallback1 = new WaitCallback(demoClass.Run1);
            //将方法排入队列,在线程池变为可用时执行
            ThreadPool.QueueUserWorkItem(waitCallback1);


            //使用委托绑定线程池要执行的方法(有参数)
            WaitCallback waitCallback2 = new WaitCallback(demoClass.Run1);
            //将方法排入队列,在线程池变为可用时执行
            ThreadPool.QueueUserWorkItem(waitCallback2,"Brambling");


            UserInfo userInfo = new UserInfo();
            userInfo.Name = "Brambling";
            userInfo.Age = 33;

            //使用委托绑定线程池要执行的方法(有参数,自定义类型的参数)
            WaitCallback waitCallback3 = new WaitCallback(demoClass.Run2);
            //将方法排入队列,在线程池变为可用时执行
            ThreadPool.QueueUserWorkItem(waitCallback3, userInfo);

            Console.WriteLine();
            Console.WriteLine("Main thread working...");
            Console.WriteLine("Main thread ID is:" + Thread.CurrentThread.ManagedThreadId.ToString());
            Console.ReadKey();
        }
    }

    public class ThreadDemoClass
    {
        public void Run1(object obj)
        {
            string name = obj as string;

            Console.WriteLine();
            Console.WriteLine("Child thread working...");
            Console.WriteLine("My name is " + name);
            Console.WriteLine("Child thread ID is:" + Thread.CurrentThread.ManagedThreadId.ToString());
        }

        public void Run2(object obj)
        {
            UserInfo userInfo=(UserInfo)obj;

            Console.WriteLine();
            Console.WriteLine("Child thread working...");
            Console.WriteLine("My name is " + userInfo.Name);
            Console.WriteLine("I'm " + userInfo.Age + " years old this year");
            Console.WriteLine("Child thread ID is:" + Thread.CurrentThread.ManagedThreadId.ToString());
        }
    }

    public class UserInfo
    {
        public string Name { get; set; }

        public int Age { get; set; }
    }

施行结果:

实践结果:

威尼斯人娱乐 15

威尼斯人娱乐 16

使用线程池建立的线程也足以接纳传递参数或不传递参数,并且参数也能够是值类型或引用类型(包蕴自定义类型)。看上边包车型客车结果发现了何等?没错,第二次施行的章程的线程ID为陆,最后三次实施的措施的线程ID也为陆。那就认证第一次请求线程池的时候,线程池建立了二个线程,当它执行到位之后就以挂起状态回到了线程池,在最终1回呼吁的时候,再次提示了该线程执行任务。那样就很简单精晓了。

使用线程池建立的线程也足以采取传递参数或不传递参数,并且参数也得以是值类型或引用类型(包含自定义类型)。看上面的结果发现了什么样?没有错,第1遍执行的点子的线程ID为陆,最终三回施行的主意的线程ID也为六。那就印证第叁遍请求线程池的时候,线程池建立了2个线程,当它实施到位之后就以挂起状态回到了线程池,在结尾1回呼吁的时候,再一次提示了该线程执行职务。那样就很不难了然了。

在那里本人还发现了三个题材,就是,每一趟运营的时候,输出的剧情的逐1都不自然是一律的。(不只是线程池,前面包车型客车也是)因为,笔者平素不给别的线程设置优先级(线程池不能够设置线程的优先级),那里实在就关系到线程安全的难点了,很明确未来这么是非线程安全的。让自家举个栗子形容一下来说,就像从前在母校下课了去吃饭1样,一拥而上,毫无秩序。

在此地本身还发现了三个难点,正是,每次运营的时候,输出的内容的1一都不自然是如出1辙的。(不只是线程池,前边的也是)因为,笔者从没给任何线程设置优先级(线程池无法安装线程的优先级),那里实在就关系到线程安全的标题了,很显然未来如此是非线程安全的。让本身举个栗子形容一下的话,就如之前在学堂下课了去就餐一样,蜂拥而上,毫无秩序。

线程安全就先不说,留在前面再说(包含前面所涉嫌的线程同步的题材),那篇博客目的在于清楚多线程。因为本身也远非太深的通晓。。。

线程安全就先不说,留在前面再说(包罗前边所涉及的线程同步的标题),那篇博客目的在于清楚二十多线程。因为自个儿也尚未太深的接头。。。

地点我们曾经落到实处了无参数和有参数以及自定义参数10贰线程的实例,可是还有一个一同的题材这就是都并没有再次回到值。当大家用拾2线程抓好在支付的时候大多数都以会须要再次回到值的,那么大家得以行使成员变量来尝试。

地点我们早就完毕了无参数和有参数以及自定义参数二10多线程的实例,但是还有3个联袂的标题那正是都未有重回值。当大家用三十二线程加强际支出的时候大多数都是会供给重返值的,那么大家能够使用成员变量来试试看。

   class Program
    {
        List<UserInfo> userInfoList = new List<UserInfo>();

        static void Main(string[] args)
        {
            Program program = new Program();

            ParameterizedThreadStart threadStart = new ParameterizedThreadStart(program.Run);
            Thread thread = null;
            UserInfo userInfo = null;


            for (int i = 0; i < 3; i++)
            {
                userInfo = new UserInfo();
                userInfo.Name = "Brambling" + i.ToString();
                userInfo.Age = 33 + i;

                thread = new Thread(threadStart);
                thread.Start(userInfo);
                thread.Join();
            }

            foreach (UserInfo user in program.userInfoList)
            {
                Console.WriteLine("My name is " + user.Name);
                Console.WriteLine("I'm " + user.Age + " years old this year");
                Console.WriteLine("Thread ID is:" + user.ThreadId);
            }

            Console.ReadKey();
        }

        public void Run(object obj)
        {
            UserInfo userInfo = (UserInfo)obj;

            userInfo.ThreadId = Thread.CurrentThread.ManagedThreadId;
            userInfoList.Add(userInfo);
        }
    }
   class Program
    {
        List<UserInfo> userInfoList = new List<UserInfo>();

        static void Main(string[] args)
        {
            Program program = new Program();

            ParameterizedThreadStart threadStart = new ParameterizedThreadStart(program.Run);
            Thread thread = null;
            UserInfo userInfo = null;


            for (int i = 0; i < 3; i++)
            {
                userInfo = new UserInfo();
                userInfo.Name = "Brambling" + i.ToString();
                userInfo.Age = 33 + i;

                thread = new Thread(threadStart);
                thread.Start(userInfo);
                thread.Join();
            }

            foreach (UserInfo user in program.userInfoList)
            {
                Console.WriteLine("My name is " + user.Name);
                Console.WriteLine("I'm " + user.Age + " years old this year");
                Console.WriteLine("Thread ID is:" + user.ThreadId);
            }

            Console.ReadKey();
        }

        public void Run(object obj)
        {
            UserInfo userInfo = (UserInfo)obj;

            userInfo.ThreadId = Thread.CurrentThread.ManagedThreadId;
            userInfoList.Add(userInfo);
        }
    }

执行结果:

实施结果:

威尼斯人娱乐 17

威尼斯人娱乐 18

用地方那种情势勉强能够满足重返值的须要,然则却有极大的局限性,因为此地我利用的是成员变量,所以也就限制了线程调用的措施必须是在同1个类里面。

用地点那种艺术勉强能够满足重返值的须要,但是却有相当大的局限性,因为此处作者使用的是成员变量,所以也就限制了线程调用的秘诀必须是在同二个类里面。

之所以也就有了下边包车型地铁不贰秘诀,使用委托异步调用的不二诀窍。

由此也就有了上面包车型客车法子,使用委托异步调用的办法。

 

 

5、异步委托

伍、异步委托

委托的异步调用有四个相比较主要的艺术:BeginInvoke()EndInvoke()

委托的异步调用有多个相比关键的方法:BeginInvoke()EndInvoke()

   class Program
    {
        //定义一个委托类
        private delegate UserInfo MyDelegate(UserInfo userInfo);


        static void Main(string[] args)
        {
            ThreadDemoClass demoClass = new ThreadDemoClass();
            List<UserInfo> userInfoList = new List<UserInfo>();
            UserInfo userInfo = null;
            UserInfo userInfoRes = null;

            //创建一个委托并绑定方法
            MyDelegate myDelegate = new MyDelegate(demoClass.Run);

            for (int i = 0; i < 3; i++)
            {
                userInfo = new UserInfo();
                userInfo.Name = "Brambling" + i.ToString();
                userInfo.Age = 33 + i;

                //传入参数并执行异步委托
                IAsyncResult result = myDelegate.BeginInvoke(userInfo,null,null);

                //异步操作是否完成
                while (!result.IsCompleted)
                {
                    Thread.Sleep(100);

                    Console.WriteLine("Main thread working...");
                    Console.WriteLine("Main thread ID is:" + Thread.CurrentThread.ManagedThreadId.ToString());
                    Console.WriteLine();
                }

                //结束异步委托,并获取返回值
                userInfoRes = myDelegate.EndInvoke(result);

                userInfoList.Add(userInfoRes);
            }

            foreach (UserInfo user in userInfoList)
            {
                Console.WriteLine("My name is " + user.Name);
                Console.WriteLine("I'm " + user.Age + " years old this year");
                Console.WriteLine("Thread ID is:" + user.ThreadId);
            }

            Console.ReadKey();
        }
    }

    public class ThreadDemoClass
    {
        public UserInfo Run(UserInfo userInfo)
        {
            userInfo.ThreadId = Thread.CurrentThread.ManagedThreadId;

            Console.WriteLine("Child thread working...");
            Console.WriteLine("Child thread ID is:" + userInfo.ThreadId);
            Console.WriteLine();

            return userInfo;
        }
    }
   class Program
    {
        //定义一个委托类
        private delegate UserInfo MyDelegate(UserInfo userInfo);


        static void Main(string[] args)
        {
            ThreadDemoClass demoClass = new ThreadDemoClass();
            List<UserInfo> userInfoList = new List<UserInfo>();
            UserInfo userInfo = null;
            UserInfo userInfoRes = null;

            //创建一个委托并绑定方法
            MyDelegate myDelegate = new MyDelegate(demoClass.Run);

            for (int i = 0; i < 3; i++)
            {
                userInfo = new UserInfo();
                userInfo.Name = "Brambling" + i.ToString();
                userInfo.Age = 33 + i;

                //传入参数并执行异步委托
                IAsyncResult result = myDelegate.BeginInvoke(userInfo,null,null);

                //异步操作是否完成
                while (!result.IsCompleted)
                {
                    Thread.Sleep(100);

                    Console.WriteLine("Main thread working...");
                    Console.WriteLine("Main thread ID is:" + Thread.CurrentThread.ManagedThreadId.ToString());
                    Console.WriteLine();
                }

                //结束异步委托,并获取返回值
                userInfoRes = myDelegate.EndInvoke(result);

                userInfoList.Add(userInfoRes);
            }

            foreach (UserInfo user in userInfoList)
            {
                Console.WriteLine("My name is " + user.Name);
                Console.WriteLine("I'm " + user.Age + " years old this year");
                Console.WriteLine("Thread ID is:" + user.ThreadId);
            }

            Console.ReadKey();
        }
    }

    public class ThreadDemoClass
    {
        public UserInfo Run(UserInfo userInfo)
        {
            userInfo.ThreadId = Thread.CurrentThread.ManagedThreadId;

            Console.WriteLine("Child thread working...");
            Console.WriteLine("Child thread ID is:" + userInfo.ThreadId);
            Console.WriteLine();

            return userInfo;
        }
    }

推行结果:

履行结果:

威尼斯人娱乐 19

威尼斯人娱乐 20

BeginInvoke() 方法用于异步委托的推行起来,EndInvoke()
方法用于停止异步委托,并得到异步委托执行到位后的重回值。IAsyncResult.IsCompleted
用于监视异步委托的施市价况(true /
false),那里的时日是不定的,也便是说一定要等到异步委托执行到位以往,这特天性才会回来
true。倘诺异步委托的主意耗费时间较长,那么主线程会从来工作下去。

BeginInvoke() 方法用于异步委托的履行起来,EndInvoke()
方法用于甘休异步委托,并赢得异步委托执行到位后的重回值。IAsyncResult.IsCompleted
用于监视异步委托的施市价况(true /
false),那里的时光是不定的,也正是说一定要等到异步委托执行到位未来,那几个性情才会回到
true。假设异步委托的艺术耗费时间较长,那么主线程会一贯工作下去。

BeginInvoke()
是还可以四个参数的,它的参数个数和参数类型取决于定义委托时的参数个数和类型,无论它有稍许个参数,尾数参数都是不变的,上边大家会说起。

BeginInvoke()
是足以承受七个参数的,它的参数个数和参数类型取决于定义委托时的参数个数和品种,无论它有微微个参数,最终七个参数都以不变的,下边大家会提起。

 

 

那正是说大家还是能用上面包车型地铁艺术
WaitOne(),自定义3个等候的时刻,倘诺在那个等待时间内异步委托未有实施到位,那么就会实施
while 里面的主线程的逻辑,反之就不会履行。

那正是说我们还足以用上边包车型客车章程
WaitOne(),自定义三个等待的小时,如果在那些等待时间内异步委托未有实行到位,那么就会履行
while 里面包车型地铁主线程的逻辑,反之就不会执行。

   class Program
    {
        //定义一个委托类
        private delegate UserInfo MyDelegate(UserInfo userInfo);


        static void Main(string[] args)
        {
            ThreadDemoClass demoClass = new ThreadDemoClass();
            List<UserInfo> userInfoList = new List<UserInfo>();
            UserInfo userInfo = null;
            UserInfo userInfoRes = null;

            //创建一个委托并绑定方法
            MyDelegate myDelegate = new MyDelegate(demoClass.Run);

            for (int i = 0; i < 3; i++)
            {
                userInfo = new UserInfo();
                userInfo.Name = "Brambling" + i.ToString();
                userInfo.Age = 33 + i;

                //传入参数并执行异步委托
                IAsyncResult result = myDelegate.BeginInvoke(userInfo,null,null);

                //阻止当前线程,直到 WaitHandle 收到信号,参数为指定等待的毫秒数
                while (!result.AsyncWaitHandle.WaitOne(1000))
                {
                    Console.WriteLine("Main thread working...");
                    Console.WriteLine("Main thread ID is:" + Thread.CurrentThread.ManagedThreadId.ToString());
                    Console.WriteLine();
                }

                //结束异步委托,并获取返回值
                userInfoRes = myDelegate.EndInvoke(result);

                userInfoList.Add(userInfoRes);
            }

            foreach (UserInfo user in userInfoList)
            {
                Console.WriteLine("My name is " + user.Name);
                Console.WriteLine("I'm " + user.Age + " years old this year");
                Console.WriteLine("Thread ID is:" + user.ThreadId);
            }

            Console.ReadKey();
        }
    }

    public class ThreadDemoClass
    {
        public UserInfo Run(UserInfo userInfo)
        {
            userInfo.ThreadId = Thread.CurrentThread.ManagedThreadId;

            Console.WriteLine("Child thread working...");
            Console.WriteLine("Child thread ID is:" + userInfo.ThreadId);
            Console.WriteLine();

            return userInfo;
        }
    }
   class Program
    {
        //定义一个委托类
        private delegate UserInfo MyDelegate(UserInfo userInfo);


        static void Main(string[] args)
        {
            ThreadDemoClass demoClass = new ThreadDemoClass();
            List<UserInfo> userInfoList = new List<UserInfo>();
            UserInfo userInfo = null;
            UserInfo userInfoRes = null;

            //创建一个委托并绑定方法
            MyDelegate myDelegate = new MyDelegate(demoClass.Run);

            for (int i = 0; i < 3; i++)
            {
                userInfo = new UserInfo();
                userInfo.Name = "Brambling" + i.ToString();
                userInfo.Age = 33 + i;

                //传入参数并执行异步委托
                IAsyncResult result = myDelegate.BeginInvoke(userInfo,null,null);

                //阻止当前线程,直到 WaitHandle 收到信号,参数为指定等待的毫秒数
                while (!result.AsyncWaitHandle.WaitOne(1000))
                {
                    Console.WriteLine("Main thread working...");
                    Console.WriteLine("Main thread ID is:" + Thread.CurrentThread.ManagedThreadId.ToString());
                    Console.WriteLine();
                }

                //结束异步委托,并获取返回值
                userInfoRes = myDelegate.EndInvoke(result);

                userInfoList.Add(userInfoRes);
            }

            foreach (UserInfo user in userInfoList)
            {
                Console.WriteLine("My name is " + user.Name);
                Console.WriteLine("I'm " + user.Age + " years old this year");
                Console.WriteLine("Thread ID is:" + user.ThreadId);
            }

            Console.ReadKey();
        }
    }

    public class ThreadDemoClass
    {
        public UserInfo Run(UserInfo userInfo)
        {
            userInfo.ThreadId = Thread.CurrentThread.ManagedThreadId;

            Console.WriteLine("Child thread working...");
            Console.WriteLine("Child thread ID is:" + userInfo.ThreadId);
            Console.WriteLine();

            return userInfo;
        }
    }

实践结果:

实行结果:

威尼斯人娱乐 21

威尼斯人娱乐 22

WaitOne()
方法只好用于监视当前线程的指标,若是要监视多少个对象能够动用 WaitAny(WaitHandle[],
int)
WaitAll (WaitHandle[] , int) 那五个艺术。

WaitOne()
方法只好用来监视当前线程的目的,如若要监视多少个对象能够运用 WaitAny(WaitHandle[],
int)
WaitAll (WaitHandle[] , int) 这五个主意。

   class Program
    {
        //定义一个委托类
        private delegate UserInfo MyDelegate(UserInfo userInfo);

        static void Main(string[] args)
        {
            ThreadDemoClass demoClass = new ThreadDemoClass();
            List<UserInfo> userInfoList = new List<UserInfo>();
            UserInfo userInfo = null;
            UserInfo userInfoRes = null;

            //创建一个委托并绑定方法
            MyDelegate myDelegate = new MyDelegate(demoClass.Run);

            for (int i = 0; i < 3; i++)
            {
                userInfo = new UserInfo();
                userInfo.Name = "Brambling" + i.ToString();
                userInfo.Age = 33 + i;

                //传入参数并执行异步委托
                IAsyncResult result = myDelegate.BeginInvoke(userInfo,null,null);
                IAsyncResult result1 = myDelegate.BeginInvoke(userInfo, null, null);

                //定义要监视的对象,不能包含对同一对象的多个引用
                WaitHandle[] waitHandles = new WaitHandle[] { result.AsyncWaitHandle, result1.AsyncWaitHandle };
                while (!WaitHandle.WaitAll(waitHandles,1000))
                {
                    Console.WriteLine("Main thread working...");
                    Console.WriteLine("Main thread ID is:" + Thread.CurrentThread.ManagedThreadId.ToString());
                    Console.WriteLine();
                }

                //结束异步委托,并获取返回值
                userInfoRes = myDelegate.EndInvoke(result);
                userInfoList.Add(userInfoRes);

                userInfoRes = myDelegate.EndInvoke(result1);
                userInfoList.Add(userInfoRes);
            }

            foreach (UserInfo user in userInfoList)
            {
                Console.WriteLine("My name is " + user.Name);
                Console.WriteLine("I'm " + user.Age + " years old this year");
                Console.WriteLine("Thread ID is:" + user.ThreadId);
            }

            Console.ReadKey();
        }
    }

    public class ThreadDemoClass
    {
        public UserInfo Run(UserInfo userInfo)
        {
            userInfo.ThreadId = Thread.CurrentThread.ManagedThreadId;

            Console.WriteLine("Child thread working...");
            Console.WriteLine("Child thread ID is:" + userInfo.ThreadId);
            Console.WriteLine();

            return userInfo;
        }
    }
   class Program
    {
        //定义一个委托类
        private delegate UserInfo MyDelegate(UserInfo userInfo);

        static void Main(string[] args)
        {
            ThreadDemoClass demoClass = new ThreadDemoClass();
            List<UserInfo> userInfoList = new List<UserInfo>();
            UserInfo userInfo = null;
            UserInfo userInfoRes = null;

            //创建一个委托并绑定方法
            MyDelegate myDelegate = new MyDelegate(demoClass.Run);

            for (int i = 0; i < 3; i++)
            {
                userInfo = new UserInfo();
                userInfo.Name = "Brambling" + i.ToString();
                userInfo.Age = 33 + i;

                //传入参数并执行异步委托
                IAsyncResult result = myDelegate.BeginInvoke(userInfo,null,null);
                IAsyncResult result1 = myDelegate.BeginInvoke(userInfo, null, null);

                //定义要监视的对象,不能包含对同一对象的多个引用
                WaitHandle[] waitHandles = new WaitHandle[] { result.AsyncWaitHandle, result1.AsyncWaitHandle };
                while (!WaitHandle.WaitAll(waitHandles,1000))
                {
                    Console.WriteLine("Main thread working...");
                    Console.WriteLine("Main thread ID is:" + Thread.CurrentThread.ManagedThreadId.ToString());
                    Console.WriteLine();
                }

                //结束异步委托,并获取返回值
                userInfoRes = myDelegate.EndInvoke(result);
                userInfoList.Add(userInfoRes);

                userInfoRes = myDelegate.EndInvoke(result1);
                userInfoList.Add(userInfoRes);
            }

            foreach (UserInfo user in userInfoList)
            {
                Console.WriteLine("My name is " + user.Name);
                Console.WriteLine("I'm " + user.Age + " years old this year");
                Console.WriteLine("Thread ID is:" + user.ThreadId);
            }

            Console.ReadKey();
        }
    }

    public class ThreadDemoClass
    {
        public UserInfo Run(UserInfo userInfo)
        {
            userInfo.ThreadId = Thread.CurrentThread.ManagedThreadId;

            Console.WriteLine("Child thread working...");
            Console.WriteLine("Child thread ID is:" + userInfo.ThreadId);
            Console.WriteLine();

            return userInfo;
        }
    }

推行结果:

履行结果:

威尼斯人娱乐 23

威尼斯人娱乐 24

WaitAll() 方法和 WaitAny() 方法都足以监视四个对象,分歧的是 WaitAll()
方法须要等待全体的监视指标都收下功率信号今后才会回到 true,不然重返false。而 WaitAny() 则是当有三个监视目的收取时限信号未来就会回来一个 int
值,这几个 int
值代表的是方今收取功率信号的监视目的的目录。注意:在概念监视指标的时候,不能包涵对同二个对象的四个引用,笔者这里是概念的几个示范,所以是例外的靶子。

WaitAll() 方法和 WaitAny() 方法都足以监视八个对象,差异的是 WaitAll()
方法须求等待全数的监视指标都收下时域信号未来才会再次来到 true,不然重返false。而 WaitAny() 则是当有3个蹲点指标收取数字信号现在就会回去三个 int
值,这些 int
值代表的是当下收取复信号的监视目标的目录。注意:在概念监视目的的时候,无法包涵对同三个对象的三个引用,小编那边是概念的三个示范,所以是见仁见智的目的。

接下去大家看上边的实施结果。咦?为何主线程未有“工作”呢?

接下去大家看下面的推行结果。咦?为啥主线程未有“工作”呢?

此间你可以在异步委托调用的 Run()
方法里面为线程设置3个几分钟恐怕越来越长的挂起时间。然后在设置监视目的那里设置一个稍差于线程挂起的时光,然后调节和测试你就能发现标题标所在了。其实也不算是难点,只是之前的驾驭有误。

此间您可以在异步委托调用的 Run()
方法里面为线程设置3个几分钟只怕更加长的挂起时间。然后在装置监视目的那里设置多个低于线程挂起的时光,然后调节和测试你就能觉察难题的所在了。其实也不到底难题,只是此前的明白有误。

实质上 WaitAll() 方法和 WaitAny()
方法设置监视目的,然后钦赐三个时光(飞秒值),那里的情致是当全数的监视目的在钦定的时光内都吸收接纳到确定性信号时(那里是指
WaitAll() 方法),就不会执行 while 里面包车型客车主线程的办事,反之就会实施。

实则 WaitAll() 方法和 WaitAny()
方法设置监视目的,然后钦定2个岁月(飞秒值),那里的意思是当有着的监视指标在内定的时光内都接受到非确定性信号时(那里是指
WaitAll() 方法),就不会履行 while 里面包车型客车主线程的行事,反之就会实施。

此间您也许会有疑点,倘若是如此,那本人把后边的逻辑非运算符去掉那不就相反了么。这么精通逻辑上是没有错的,可是本身大概要说的是,尽量不要去品味,因为那会是个死循环。WaitAny()
这几个办法也是同1的知道,区别的是,它不须求等到全体的监视指标都收下时域信号,它只须求二个蹲点指标吸收能量信号就够了,那里就不在演示了。

此处您或然会有疑点,借使是如此,那自身把后面包车型客车逻辑非运算符去掉那不就相反了么。这么精晓逻辑上是没有错的,不过自己依然要说的是,尽量不要去品味,因为那会是个死循环。WaitAny()
这么些办法也是同等的明亮,分化的是,它不需求等到全部的监视指标都吸收信号,它只需要2个蹲点指标吸收复信号就够了,那里就不在演示了。

威尼斯人娱乐, 

 

地方的方法能够看看,大家纵然使用的是异步的法子调用的办法,但是依然需求等待异步的点子重返执行的结果,尽管我们得以不封堵主线程,可是如故觉得不太便宜。所以也就有了本篇博客最终三个要点,异步委托的回调函数

地点的法子能够看到,大家尽管使用的是异步的办法调用的办法,然则依旧需求等待异步的点子重回执行的结果,尽管大家能够不封堵主线程,不过照旧觉得不太便宜。所以也就有了本篇博客最终一个要点,异步委托的回调函数

   class Program
    {
        //定义一个委托类
        private delegate UserInfo MyDelegate(UserInfo userInfo);
static void Main(string[] args)
        {
            ThreadDemoClass demoClass = new ThreadDemoClass();
            UserInfo userInfo = null;

            //创建一个委托并绑定方法
            MyDelegate myDelegate = new MyDelegate(demoClass.Run);

            //创建一个回调函数的委托
            AsyncCallback asyncCallback = new AsyncCallback(Complete);

            for (int i = 0; i < 3; i++)
            {
                userInfo = new UserInfo();
                userInfo.Name = "Brambling" + i.ToString();
                userInfo.Age = 33 + i;

                //传入参数并执行异步委托,并设置回调函数
                IAsyncResult result = myDelegate.BeginInvoke(userInfo, asyncCallback, null);
            }

            Console.WriteLine("Main thread working...");
            Console.WriteLine("Main thread ID is:" + Thread.CurrentThread.ManagedThreadId.ToString());
            Console.WriteLine();

            Console.ReadKey();
        }

        public static void Complete(IAsyncResult result)
        {
            UserInfo userInfoRes = null;

            AsyncResult asyncResult = (AsyncResult)result;

            //获取在其上调用异步调用的委托对象
            MyDelegate myDelegate = (MyDelegate)asyncResult.AsyncDelegate;

            //结束在其上调用的异步委托,并获取返回值
            userInfoRes = myDelegate.EndInvoke(result);

            Console.WriteLine("My name is " + userInfoRes.Name);
            Console.WriteLine("I'm " + userInfoRes.Age + " years old this year");
            Console.WriteLine("Thread ID is:" + userInfoRes.ThreadId);
        }
    }

    public class ThreadDemoClass
    {
        public UserInfo Run(UserInfo userInfo)
        {
            userInfo.ThreadId = Thread.CurrentThread.ManagedThreadId;

            Console.WriteLine("Child thread working...");
            Console.WriteLine("Child thread ID is:" + userInfo.ThreadId);
            Console.WriteLine();

            return userInfo;
        }
    }
   class Program
    {
        //定义一个委托类
        private delegate UserInfo MyDelegate(UserInfo userInfo);
static void Main(string[] args)
        {
            ThreadDemoClass demoClass = new ThreadDemoClass();
            UserInfo userInfo = null;

            //创建一个委托并绑定方法
            MyDelegate myDelegate = new MyDelegate(demoClass.Run);

            //创建一个回调函数的委托
            AsyncCallback asyncCallback = new AsyncCallback(Complete);

            for (int i = 0; i < 3; i++)
            {
                userInfo = new UserInfo();
                userInfo.Name = "Brambling" + i.ToString();
                userInfo.Age = 33 + i;

                //传入参数并执行异步委托,并设置回调函数
                IAsyncResult result = myDelegate.BeginInvoke(userInfo, asyncCallback, null);
            }

            Console.WriteLine("Main thread working...");
            Console.WriteLine("Main thread ID is:" + Thread.CurrentThread.ManagedThreadId.ToString());
            Console.WriteLine();

            Console.ReadKey();
        }

        public static void Complete(IAsyncResult result)
        {
            UserInfo userInfoRes = null;

            AsyncResult asyncResult = (AsyncResult)result;

            //获取在其上调用异步调用的委托对象
            MyDelegate myDelegate = (MyDelegate)asyncResult.AsyncDelegate;

            //结束在其上调用的异步委托,并获取返回值
            userInfoRes = myDelegate.EndInvoke(result);

            Console.WriteLine("My name is " + userInfoRes.Name);
            Console.WriteLine("I'm " + userInfoRes.Age + " years old this year");
            Console.WriteLine("Thread ID is:" + userInfoRes.ThreadId);
        }
    }

    public class ThreadDemoClass
    {
        public UserInfo Run(UserInfo userInfo)
        {
            userInfo.ThreadId = Thread.CurrentThread.ManagedThreadId;

            Console.WriteLine("Child thread working...");
            Console.WriteLine("Child thread ID is:" + userInfo.ThreadId);
            Console.WriteLine();

            return userInfo;
        }
    }

实施结果:

举行理并了结果:

威尼斯人娱乐 25

威尼斯人娱乐 26

从上面能够见见主线程再进行了异步委托随后继续执行了下来,然后在回调函数里输出了音信,也正是说在调用了异步委托随后就随便了,把将来的扫尾委托和取得委托的归来值放到了回调函数中,因为回调函数是尚未返回值的,可是回调函数能够有三个参数。上边谈到的
BeginInvoke()
方法的终极七个参数,它的尾数第三个参数正是一个回调函数的委托,最后1个参数可以安装传入回调函数的参数。如下:

从地方能够看出主线程再履行了异步委托随后继续执行了下去,然后在回调函数里输出了音讯,也正是说在调用了异步委托随后就不管了,把现在的完结委托和获取委托的回到值放到了回调函数中,因为回调函数是平昔不再次来到值的,但是回调函数能够有三个参数。上面提及的
BeginInvoke()
方法的末尾多少个参数,它的尾数第三个参数正是1个回调函数的嘱托,最终八个参数能够安装传入回调函数的参数。如下:

   class Program
    {
        //定义一个委托类
        private delegate UserInfo MyDelegate(UserInfo userInfo);

        static List<UserInfo> userInfoList = new List<UserInfo>();

        static void Main(string[] args)
        {
            ThreadDemoClass demoClass = new ThreadDemoClass();
            UserInfo userInfo = null;

            //创建一个委托并绑定方法
            MyDelegate myDelegate = new MyDelegate(demoClass.Run);

            //创建一个回调函数的委托
            AsyncCallback asyncCallback = new AsyncCallback(Complete);

            //回调函数的参数
            string str = "I'm the parameter of the callback function!";

            for (int i = 0; i < 3; i++)
            {
                userInfo = new UserInfo();
                userInfo.Name = "Brambling" + i.ToString();
                userInfo.Age = 33 + i;

                //传入参数并执行异步委托,并设置回调函数
                IAsyncResult result = myDelegate.BeginInvoke(userInfo, asyncCallback, str);
            }

            Console.WriteLine("Main thread working...");
            Console.WriteLine("Main thread ID is:" + Thread.CurrentThread.ManagedThreadId.ToString());
            Console.WriteLine();

            Console.ReadKey();
        }

        public static void Complete(IAsyncResult result)
        {
            UserInfo userInfoRes = null;

            AsyncResult asyncResult = (AsyncResult)result;

            //获取在其上调用异步调用的委托对象
            MyDelegate myDelegate = (MyDelegate)asyncResult.AsyncDelegate;

            //结束在其上调用的异步委托,并获取返回值
            userInfoRes = myDelegate.EndInvoke(result);

            Console.WriteLine("My name is " + userInfoRes.Name);
            Console.WriteLine("I'm " + userInfoRes.Age + " years old this year");
            Console.WriteLine("Thread ID is:" + userInfoRes.ThreadId);

            //获取回调函数的参数
            string str = result.AsyncState as string;
            Console.WriteLine(str);
        }
    }

    public class ThreadDemoClass
    {
        public UserInfo Run(UserInfo userInfo)
        {
            userInfo.ThreadId = Thread.CurrentThread.ManagedThreadId;

            Console.WriteLine("Child thread working...");
            Console.WriteLine("Child thread ID is:" + userInfo.ThreadId);
            Console.WriteLine();

            return userInfo;
        }
    }
   class Program
    {
        //定义一个委托类
        private delegate UserInfo MyDelegate(UserInfo userInfo);

        static List<UserInfo> userInfoList = new List<UserInfo>();

        static void Main(string[] args)
        {
            ThreadDemoClass demoClass = new ThreadDemoClass();
            UserInfo userInfo = null;

            //创建一个委托并绑定方法
            MyDelegate myDelegate = new MyDelegate(demoClass.Run);

            //创建一个回调函数的委托
            AsyncCallback asyncCallback = new AsyncCallback(Complete);

            //回调函数的参数
            string str = "I'm the parameter of the callback function!";

            for (int i = 0; i < 3; i++)
            {
                userInfo = new UserInfo();
                userInfo.Name = "Brambling" + i.ToString();
                userInfo.Age = 33 + i;

                //传入参数并执行异步委托,并设置回调函数
                IAsyncResult result = myDelegate.BeginInvoke(userInfo, asyncCallback, str);
            }

            Console.WriteLine("Main thread working...");
            Console.WriteLine("Main thread ID is:" + Thread.CurrentThread.ManagedThreadId.ToString());
            Console.WriteLine();

            Console.ReadKey();
        }

        public static void Complete(IAsyncResult result)
        {
            UserInfo userInfoRes = null;

            AsyncResult asyncResult = (AsyncResult)result;

            //获取在其上调用异步调用的委托对象
            MyDelegate myDelegate = (MyDelegate)asyncResult.AsyncDelegate;

            //结束在其上调用的异步委托,并获取返回值
            userInfoRes = myDelegate.EndInvoke(result);

            Console.WriteLine("My name is " + userInfoRes.Name);
            Console.WriteLine("I'm " + userInfoRes.Age + " years old this year");
            Console.WriteLine("Thread ID is:" + userInfoRes.ThreadId);

            //获取回调函数的参数
            string str = result.AsyncState as string;
            Console.WriteLine(str);
        }
    }

    public class ThreadDemoClass
    {
        public UserInfo Run(UserInfo userInfo)
        {
            userInfo.ThreadId = Thread.CurrentThread.ManagedThreadId;

            Console.WriteLine("Child thread working...");
            Console.WriteLine("Child thread ID is:" + userInfo.ThreadId);
            Console.WriteLine();

            return userInfo;
        }
    }

实行理并了结果:

履行结果:

威尼斯人娱乐 27

威尼斯人娱乐 28

回调函数的参数也是 object 类型的,笔者那里用的是二个 string
类型,可是它也得以是自定义类型的参数。

回调函数的参数也是 object 类型的,笔者那边用的是三个 string
类型,可是它也可以是自定义类型的参数。

本篇博客到此甘休,在写那篇博客的同时也让自身个人对多线程编制程序加深了明白,四线程编制程序的知识点还有为数不少,前边再持续与大家大快朵颐。

本篇博客到此甘休,在写那篇博客的同时也让作者个人对多线程编制程序加深了精晓,十二线程编制程序的知识点还有许多,后边再持续与大家享受。

 

 

参考:

参考:

http://www.cnblogs.com/leslies2/archive/2012/02/07/2310495.html#t1

http://www.cnblogs.com/leslies2/archive/2012/02/07/2310495.html#t1

 

 

相关文章