多线程编制程序第三步葡京娱乐注册

一、进度、线程及八线程的概念

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

什么是四线程呢?不领悟。

哪些是多线程呢?不了解。

那怎么样是线程呢?聊到线程就不得不说说经过。小编在网上搜索也查找了有些资料,大多数所说的经超过实际际是很空虚的东西。通俗的来讲,进度正是贰个应用程序开首运转,那么那几个应用程序就会设有1个属于这一个应用程序的长河。

那怎么是线程呢?聊到线程就只可以说说经过。作者在网上搜索也查找了有个别素材,当先1/二所说的经超过实际际是很空虚的事物。通俗的来讲,进程正是1个应用程序初叶运维,那么这些应用程序就会设有多个属于那个应用程序的进程。

那正是说线程正是经过中的基本进行单元,各个进程中都至少存在着2个线程,那一个线程是依据进度创设而创制的,所以那一个线程大家称为主线程。那么拾贰线程就是含有有除了主线程之外的任何线程。假诺2个线程可以实行一个义务,那么二十多线程正是能够同时推行八个职责。

那就是说线程正是经过中的基本进行单元,种种进程中都至少存在着贰个线程,这么些线程是依照进度创造而创建的,所以那几个线程大家称为主线程。那么二10十二线程就是含有有除了主线程之外的任何线程。假诺3个线程能够实施1个职责,那么10二线程正是能够而且进行四个职分。

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

上述的定义纯属个人通晓,如有啥窘迫的地点,还请多多指正。

 

 

二、线程的基本知识

2、线程的基本知识

Thread 类

Thread 类

Thread 类是用来控制线程的基本功类,它存在于 System.Threading
命名空间。通过 Thread
能够操纵当前使用程序域中线程的成立、挂起、甘休、销毁。

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

Thread 1些常用属性:

Thread 壹些常用属性:

葡京娱乐注册 1

葡京娱乐注册 2

Thread 一些常用方法:

Thread 壹些常用方法:

葡京娱乐注册 3

葡京娱乐注册 4

Thread 的先期级:

Thread 的先行级:

葡京娱乐注册 5

葡京娱乐注册 6

 

 

3、三十二线程的简练示例

3、多线程的简约示例

上边就从简单的二1010二线程初步驾驭呢,那里本身创造了三个控制台应用程序。

上边就从简单的多线程初始驾驭吧,那里我创造了2个控制台应用程序。

   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

基于以上的结果大家得以分析获得,主线程创立了1个子线程并运转了它,不过主线程未有等到子线程执行到位,而是继续再往下实施的。

依照上述的结果大家得以分析获得,主线程创造了2个子线程并运行了它,不过主线程未有等到子线程执行到位,而是继续再往下进行的。

那就关乎到了线程异步或共同的题材了,那几个咱们后边再说。

那就涉及到了线程异步或伙同的标题了,这几个大家后边再说。

三番八遍下面的难点,那么只要作者想要等到子线程执行到位现在再持续主线程的工作吗(当然,笔者以为壹般不会有那种需要)。

接二连三上边的难题,那么只要本身想要等到子线程执行到位现在再持续主线程的做事啊(当然,小编觉着1般不会有那种供给)。

作者们可以选用 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(),它的作用正是用来阻塞前面包车型大巴线程,直到方今线程完毕以往。当然,还有其余的不2秘籍能够成功,比如大家明天把
thread.Join() 换来

上边的代码相比较在此之前就添加了一句
thread.Join(),它的效应便是用来阻塞前面包车型客车线程,直到如今线程完结之后。当然,还有别的的章程能够形成,比如大家以后把
thread.Join() 换到

上面那句代码。

下边那句代码。

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

就现阶段的场景来说,那样真的能够知足须求,可是那样做有多个弊端,正是,当子线程所执行的不二等秘书籍逻辑相比复杂耗费时间较长的时候,那样的不贰法门就不必然能够,即使能够修改线程挂起的时间,不过这么些执行的时间却是不定的。所以,Thread.Sleep()
方法一般用来设置二十八线程之间进行的间隔时间的。

就当下的情景来说,那样真的能够满意急需,不过如此做有三个害处,正是,当子线程所进行的法子逻辑比较复杂耗时较长的时候,那样的法子就不肯定能够,固然能够修改线程挂起的日子,可是这么些执行的日子却是不定的。所以,Thread.Sleep()
方法一般用来设置二十多线程之间实行的间隔时间的。

别的,Join()
方法也经受3个参数,该参数用于内定阻塞线程的时刻,假使在内定的时刻内该线程未有停下,那么就回到
false,假诺在钦命的日子内已偃旗息鼓,那么就再次来到 true。

此外,Join()
方法也承受一个参数,该参数用于钦命阻塞线程的岁月,即便在钦点的小时内该线程未有结束,那么就赶回
false,即便在内定的时间内已告1段落,那么就回到 true。

 

 

地点的那种应用多线程的章程只是大约的出口壹段内容而已,多数景色下我们要求对线程调用的艺术传入参数和接收再次回到值的,然而地点那种措施是不收受参数并且未有重回值的,那么大家能够使用 ParameterizedThreadStart
委托来创设十贰线程,那些委托能够承受一个 object
类型的参数,大家得以在那下边做小说。

上边的那种使用二十四线程的不二等秘书籍只是简约的出口一段内容而已,多数情景下咱们供给对线程调用的方法传入参数和接收再次来到值的,但是地点那种办法是不收受参数并且未有再次来到值的,那么大家得以选取 ParameterizedThreadStart
委托来成立多线程,这几个委托可以承受3个 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()
运行的线程暗中同意为前台线程。那么前台线程和后台线程有如何分别呢?

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

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

那正是说地点的结果能够见到在三十二线程实现了参数的传递,然而它也唯有1个参数呢。可是它接受的参数是
object
类型的(万类之源),也正是说既能够是值类型或引用类型,也足以是自定义类型。(当然,自定义类型其实也是属于引用类型的)下边大家应用自定义类型作为参数字传送递。

那便是说地点的结果能够见见在多线程达成了参数的传递,可是它也唯有3个参数呢。但是它承受的参数是
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宝马X3初步化的时候立时创造线程的,而是在应用程序要创设线程来执行职分的时候,线程池才会开首化二个线程,初叶化的线程和任何线程一样,可是在线程实现任务之后不会活动销毁,而是以挂起的图景回到线程池。当应用程序再一次向现成池发出请求的时候,线程池里挂起的线程会再次激活执行职务。那样做能够减掉线程创立和销毁所拉动的开销。线程池建立的线程暗许为后台线程

利用 ThreadStart 和 ParameterizedThreadStart
创设线程依旧比较简单的,然则出于线程的创导和销毁供给开支一定的支付,过多的运用线程反而会招致内部存款和储蓄器财富的荒废,从而影响属性,出于对品质的思量,于是引进了线程池的概念。线程池并不是在
CLCRUISER发轫化的时候立时创立线程的,而是在应用程序要创建线程来执行职分的时候,线程池才会先导化贰个线程,初阶化的线程和其它线程一样,可是在线程实现任务之后不会活动销毁,而是以挂起的动静回到线程池。当应用程序再度向现成池发出请求的时候,线程池里挂起的线程会再次激活执行职责。那样做能够减掉线程创制和销毁所带来的花费。线程池建立的线程默许为后台线程

   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为6,最终2回施行的格局的线程ID也为六。这就表达第3遍请求线程池的时候,线程池建立了三个线程,当它执行到位现在就以挂起状态回到了线程池,在最终一次呼吁的时候,再一次提示了该线程执行职分。那样就很简单掌握了。

使用线程池建立的线程也足以采纳传递参数或不传递参数,并且参数也能够是值类型或引用类型(包括自定义类型)。看下边的结果发现了如何?没有错,第3次实践的诀窍的线程ID为陆,最终一遍进行的章程的线程ID也为陆。这就证实第二回请求线程池的时候,线程池建立了1个线程,当它执行到位以往就以挂起状态回到了线程池,在终极贰次呼吁的时候,再一次提示了该线程执行任务。那样就很简单精通了。

在此间笔者还发现了多个标题,正是,每一次运营的时候,输出的始末的顺序都不必然是一样的。(不只是线程池,前边的也是)因为,小编尚未给其余线程设置优先级(线程池不可能设置线程的优先级),那里其实就涉及到线程安全的题材了,很扎眼将来那般是非线程安全的。让本身举个栗子形容一下以来,就如从前在学堂下课了去用餐1样,一拥而上,毫无秩序。

在此处笔者还发现了3个题材,就是,每一回运维的时候,输出的剧情的相继都不自然是平等的。(不只是线程池,前边的也是)因为,小编并未有给其余线程设置优先级(线程池无法设置线程的优先级),那里其实就提到到线程安全的问题了,很强烈今后那般是非线程安全的。让本身举个栗子形容一下的话,就好像在此在此以前在该校下课了去就餐壹样,蜂拥而上,毫无秩序。

线程安全就先不说,留在后边再说(包蕴前边所提到的线程同步的难点),那篇博客意在清楚多线程。因为本身也尚无太深的通晓。。。

线程安全就先不说,留在前边再说(包罗前面所关联的线程同步的题材),那篇博客目的在于清楚多线程。因为本身也未尝太深的领悟。。。

地方大家曾经落到实处了无参数和有参数以及自定义参数拾2线程的实例,然则还有三个合伙的难题那正是都并未重临值。当大家用多线程抓实在支付的时候大多数都以会须要重返值的,那么大家得以利用成员变量来试试看。

地点大家早就落到实处了无参数和有参数以及自定义参数二十四线程的实例,不过还有多少个联机的题材那正是都并未有重临值。当我们用四线程狠抓在支付的时候大多数都以会须要再次回到值的,那么大家得以运用成员变量来尝试。

   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

用地点这种方法勉强能够知足再次回到值的需要,不过却有相当的大的局限性,因为此地自身利用的是成员变量,所以也就限制了线程调用的法子必须是在同四个类里面。

用地点那种艺术可以接受满意重返值的要求,不过却有极大的局限性,因为此地自身使用的是成员变量,所以也就限制了线程调用的不二秘诀必须是在同贰个类里面。

因而也就有了上边包车型客车办法,使用委托异步调用的点子。

从而也就有了下边包车型地铁章程,使用委托异步调用的章程。

 

 

五、异步委托

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(),自定义2个守候的日子,即便在那些等待时间内异步委托未有实施到位,那么就会实施
while 里面包车型大巴主线程的逻辑,反之就不会进行。

那就是说大家还足以用上边包车型地铁艺术
WaitOne(),自定义3个等待的时刻,假诺在那些等待时间内异步委托未有进行到位,那么就会履行
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() 则是当有3个蹲点目的吸收实信号今后就会重返多少个 int
值,这一个 int
值代表的是眼前收取时限信号的监视目标的目录。注意:在概念监视目的的时候,不可能包涵对同三个对象的三个引用,小编那边是概念的七个示范,所以是见仁见智的目的。

WaitAll() 方法和 WaitAny() 方法都得以监视多少个目标,分化的是 WaitAll()
方法必要静观其变全部的监视指标都收到非实信号之后才会回到 true,不然再次来到false。而 WaitAny() 则是当有多少个监视目的吸收时域信号之后就会回来一个 int
值,那些 int
值代表的是现阶段接收时限信号的监视目的的目录。注意:在概念监视指标的时候,不可能蕴涵对同三个对象的多少个引用,笔者那边是概念的八个示范,所以是不一致的指标。

接下去我们看上面的举办结果。咦?为何主线程没有“工作”呢?

接下去我们看上边的施行结果。咦?为何主线程没有“工作”呢?

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

此处你能够在异步委托调用的 Run()
方法里面为线程设置一个几分钟也许越来越长的挂起时间。然后在安装监视目的那里安装叁个稍差于线程挂起的年华,然后调节和测试你就能窥见题指标所在了。其实也不到底难点,只是此前的知道有误。

其实 WaitAll() 方法和 WaitAny()
方法设置监视目的,然后钦定1个光阴(阿秒值),那里的意味是当有着的监视目的在钦点的时光内都接受到时域信号时(那里是指
WaitAll() 方法),就不会履行 while 里面包车型地铁主线程的行事,反之就会执行。

实际上 WaitAll() 方法和 WaitAny()
方法设置监视目的,然后钦点叁个年华(微秒值),那里的意味是当全部的监视目的在内定的年华内都接到到功率信号时(那里是指
WaitAll() 方法),就不会进行 while 里面包车型大巴主线程的做事,反之就会履行。

此处你只怕会有疑点,假设是这么,那作者把前面包车型地铁逻辑非运算符去掉那不就相反了么。这么掌握逻辑上是没有错的,可是我要么要说的是,尽量不要去品尝,因为那会是个死循环。WaitAny()
那一个措施也是同样的了然,分裂的是,它不必要等到全部的监视指标都收到时域信号,它只要求一个监视目的收取复信号就够了,那里就不在演示了。

此处您恐怕会有疑问,若是是那样,这小编把前边的逻辑非运算符去掉那不就相反了么。这么清楚逻辑上是没有错的,可是本人或然要说的是,尽量不要去尝尝,因为那会是个死循环。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()
方法的末尾多个参数,它的尾数第二个参数正是2个回调函数的信托,最终一个参数能够安装传入回调函数的参数。如下:

葡京娱乐注册,从下边能够看到主线程再实践了异步委托随后继续执行了下去,然后在回调函数里输出了音讯,也正是说在调用了异步委托随后就随便了,把以往的达成委托和获得委托的归来值放到了回调函数中,因为回调函数是绝非重临值的,但是回调函数能够有一个参数。上边说起的
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 类型的,作者那边用的是1个 string
类型,但是它也能够是自定义类型的参数。

本篇博客到此结束,在写那篇博客的同时也让自己个人对二十四线程编程加深了知情,拾2线程编程的知识点还有很多,前边再持续与我们大快朵颐。

本篇博客到此截止,在写那篇博客的同时也让自家个人对二十多线程编制程序加深了知情,四线程编程的知识点还有不少,后边再持续与大家享受。

 

 

参考:

参考:

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

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