汇总揭秘

CurrentThread是最常用的2个性质,它是用来获取当前运作的线程。

        delegate string MyDelegate(string name);

当要监视两个运维指标的时候,使用IAsyncResult.WaitHandle.WaitOne可就派不上用场了。
还好.NET为WaitHandle准备了其余多少个静态方法:WaitAny(waitHandle[],
int)与WaitAll (waitHandle[] , int)。
在那之中WaitAll在等候全体waitHandle完毕后再重返三个bool值。
而WaitAny是等待之中3个waitHandle实现后就回去贰个int,这些int是象征已成功waitHandle在waitHandle[]中的数组索引。
下边正是采取WaitAll的例子,运维结果与运用 IAsyncResult.IsCompleted
相同。

信托结果包罗首要措施

除此以外,也能够行使WailHandle达成同样的劳作,WaitHandle里面含有有三个艺术WaitOne(int
timeout),它能够判定委托是不是到位工作,在劳作未成功前主线程能够持续其他干活。运行上面代码可收获与使用
IAsyncResult.IsCompleted 同样的结果,而且更简便方便 。

A首先注脚 委托和事件

   

当调用Invoke()方法时,对应此委托的兼具办法都会被执行。而BeginInvoke与EndInvoke则支持委托方法的异步调用,由BeginInvoke运营的线程都属于CLOdyssey线程池中的工作者线程,在上面将详细表达。

ManagedThreadId是肯定线程的唯一标识符,程序在大多数情状下都以经过Thread.ManagedThreadId来鉴定区别线程的。而Name是三个可变值,在暗许时候,Name为三个空值
Null,开发人士能够因此程序设置线程的名称,但那只是1个救助功效。

thread.Start();

运维结果如下


1 class Program
2 {
3 delegate string MyDelegate(string name);
4
5 static void Main(string[] args)
6 {
7 ThreadMessage(“Main Thread”);
8
玖 //建立法委员会委员托
10 MyDelegate myDelegate = new MyDelegate(Hello);
11
1二 //异步调用委托,获取总计结果
13 IAsyncResult result=myDelegate.BeginInvoke(“Leslie”, null, null);
14
15 //此处可进入七个检查评定对象
16 WaitHandle[] waitHandleList = new WaitHandle[] {
result.AsyncWaitHandle,…….. };
17 while (!WaitHandle.WaitAll(waitHandleList,200))
18 {
19 Console.WriteLine(“Main thead do work!”);
20 }
21 string data=myDelegate.EndInvoke(result);
22 Console.WriteLine(data);
23
24 Console.ReadKey();
25 }
26
27 static string Hello(string name)
28 {
29 ThreadMessage(“Async Thread”);
30 Thread.Sleep(2000);
31 return “Hello ” + name;
32 }
33
34 static void ThreadMessage(string data)
35 {
36 string message = string.Format(“{0}\n ThreadId is:{1}”,
37 data,Thread.CurrentThread.ManagedThreadId);
38 Console.WriteLine(message);
39 }
40 }

                if (ShowUpdate != null) ShowUpdate(message);

图片 1

loginForm.ShowUpdate += new LoginForm.DisplayUpdate(loginincallback);

行使CL宝马X3线程池中的工作者线程,最灵敏最常用的不二诀窍正是接纳委托的异步方法,在此先简单介绍一下委托类。

Thread thread = new Thread(new ThreadStart());

1 namespace Test
2 {
3 class Program
4 {
5 delegate string MyDelegate(string name);
6
7 static void Main(string[] args)
8 {
9 ThreadMessage(“Main Thread”);
10
1一 //建立委托
12 MyDelegate myDelegate = new MyDelegate(Hello);
13
1四 //异步调用委托,获取计算结果
15 IAsyncResult result=myDelegate.BeginInvoke(“Leslie”, null, null);
16
17 while (!result.AsyncWaitHandle.WaitOne(200))
18 {
19 Console.WriteLine(“Main thead do work!”);
20 }
21 string data=myDelegate.EndInvoke(result);
22 Console.WriteLine(data);
23
24 Console.ReadKey();
25 }
26
27 static string Hello(string name)
28 {
29 ThreadMessage(“Async Thread”);
30 Thread.Sleep(2000);
31 return “Hello ” + name;
32 }
33
34 static void ThreadMessage(string data)
35 {
36 string message = string.Format(“{0}\n ThreadId is:{1}”,
37 data,Thread.CurrentThread.ManagedThreadId);
38 Console.WriteLine(message);
39 }
40 }

缺陷:不可带多少个参数,不可重回值

图片 2

thread.join();

归来目录

A调用事件,落成广播成效

目录

            Console.ReadKey();
        }

图片 3

        static string Hello(string name)
        {
            ThreadMessage(“Async Thread”);
            Thread.Sleep(2000);
            return “Hello ” + name;
        }

   

class Program
    {
        public class Person
        {
            public string Name;
            public int Age;
        }

4、CLTiguan线程池的劳重力线程

B 定义A的实例并 注册事件

运作结果

可传参数,可获得重临值,可跟踪线程状态,线程甘休后可回调钦点方法,并可含蓄自定义参数

   

由此线程池控制:

利用CL奥迪Q7线程池的劳重力线程一般有二种方式,一是直接通过
ThreadPool.QueueUserWorkItem() 方法,贰是经过信托,上面将逐条细说。

class Program
    {
        delegate void MyDelegate();

引言

thread.Start(object);

图片 4

            Console.WriteLine(data+”\n”+message);
        }

图片 5

            //此处可加入多个检查实验对象
            WaitHandle[] waitHandleList = new WaitHandle[] {
result.AsyncWaitHandle,…….. };
            while (!WaitHandle.WaitAll(waitHandleList,200))
            {
                Console.WriteLine(“Main thead do work!”);
            }

   

        static void Main(string[] args)
        {
            MyDelegate delegate1 = new MyDelegate(METHOD);
            var methods=delegate1.GetType().GetMethods();
            if (methods != null)
                foreach (MethodInfo info in methods)
                    Console.WriteLine(info.Name);
            Console.ReadKey();
         }
     }

运转结果

新建线程 ,无重返值,带参数

CL翼虎线程池分为工作者线程(workerThreads)与I/O线程
(completionPortThreads)
两种,工小编线程是第三用作管理CLGL450内部对象的周转,I/O(Input/Output)
线程顾名思义是用于与表面系统调换音讯,IO线程的底细将在下1节详细表达。

          //同等方法完毕上述操作

转载:http://www.cnblogs.com/leslies2/archive/2012/02/07/2310495.html\#undefined

public class MyDelegate:MulticastDelegate
    {
        public MyDelegate(object target, int methodPtr);
        //调用委托方法
        public virtual void Invoke();
        //异步委托
        public virtual IAsyncResult BeginInvoke(AsyncCallback
callback,object state);
        public virtual void EndInvoke(IAsyncResult result);
    }

委托类包含以下多少个重点措施

寄托实例首要艺术

图片 6

新建线程,无重临值,不带参

图片 7

 //打消终止,继续执行线程
Thread.ResetAbort();

为了等待别的后台线程完成后再结束主线程,就能够利用Thread.Sleep()方法。

当要监视四个运营指标的时候,使用IAsyncResult.WaitHandle.WaitOne可就派不上用场了。
幸好.NET为WaitHandle准备了此外八个静态方法:WaitAny(waitHandle[],
int)与WaitAll (waitHandle[] , int)。
里面WaitAll在等候全部waitHandle完结后再回来三个bool值。
而WaitAny是伺机之中3个waitHandle实现后就回到八个int,这一个int是意味已形成waitHandle在waitHandle[]中的数组索引。
上边正是使用WaitAll的例证,运转结果与应用 IAsyncResult.IsCompleted
相同。

采用轮询格局来检查评定异步方法的动静不行费劲,而且成效不高,有见及此,.NET为
IAsyncResult BeginInvoke(AsyncCallback ,
object)准备了1个回调函数。使用 AsyncCallback
就足以绑定一个主意作为回调函数,回调函数必须是带参数 IAsyncResult
且无再次来到值的办法: void AsycnCallbackMethod(IAsyncResult result)
。在BeginInvoke方法成功后,系统就会调用AsyncCallback所绑定的回调函数,最终回调函数中调用
XXX EndInvoke(IAsyncResult result)
就足以了结异步方法,它的回来值类型与信托的重返值1致。

           while (!result.AsyncWaitHandle.WaitOne(200))
            {
                Console.WriteLine(“Main thead do work!”);
            }
            string data=myDelegate.EndInvoke(result);
            Console.WriteLine(data);
           
            Console.ReadKey();
        }

   

若果想为回调函数字传送送1些外表音讯,就能够利用BeginInvoke(AsyncCallback,object)的尾声二个参数object,它同意外部向回调函数输入任何项指标参数。只必要在回调函数中动用
AsyncResult.AsyncState 就能够收获object对象。

运维结果:

        static void Main(string[] args)
        {
            ThreadMessage(“Main Thread”);
           
            //建立法委员会委员托
            MyDelegate myDelegate = new MyDelegate(Hello);
            //异步调用委托,获取总括结果
            IAsyncResult result=myDelegate.BeginInvoke(“Leslie”, null,
null);
            //在异步线程未形成前实施此外干活
            while (!result.IsCompleted)

4.贰 工小编线程与I/O线程

        static void Completed(IAsyncResult result)
        {
            ThreadMessage(“Async Completed”);

1 public class MyDelegate:MulticastDelegate
2 {
3 public MyDelegate(object target, int methodPtr);
四 //调用委托方法
5 public virtual void Invoke();
六 //异步委托
7 public virtual IAsyncResult BeginInvoke(AsyncCallback callback,object
state);
8 public virtual void EndInvoke(IAsyncResult result);
9 }

BeginInvoke,不调用回调函数方法  ,代码实例:

类    

说明

AutoResetEvent

通知正在等待的线程已发生事件。无法继承此类。

ExecutionContext

管理当前线程的执行上下文。无法继承此类。

Interlocked

为多个线程共享的变量提供原子操作。

Monitor

提供同步对对象的访问的机制。

Mutex

一个同步基元,也可用于进程间同步。

Thread

创建并控制线程,设置其优先级并获取其状态。

ThreadAbortException

在对 Abort 方法进行调用时引发的异常。无法继承此类。

ThreadPool

提供一个线程池,该线程池可用于发送工作项、处理异步 I/O、代表其他线程等待以及处理计时器。

Timeout

包含用于指定无限长的时间的常数。无法继承此类。

Timer

提供以指定的时间间隔执行方法的机制。无法继承此类。

WaitHandle

封装等待对共享资源的独占访问的操作系统特定的对象。

主线程等待异步线程运行结束后继续执行

   

劳力线程,直接行使格局,无重临值,需传递object对象,可不带参数暗许为null

图片 8

号外引申:

注意上述三个例证都未曾应用Console.ReadKey(),但系统如故会等待异步线程达成后才会终结。那是因为运用Thread.Start()运行的线程暗中认可为前台线程,而系统必须等待全体前台线程运营截止后,应用程序域才会自动卸载。

        public delegate void DisplayUpdate(string message);
        //评释事件
        public event DisplayUpdate ShowUpdate;

图片 9

        static void Main(string[] args)
        {
            ThreadMessage(“Main Thread”);

选用 ThreadPool.QueueUserWorkItem(WaitCallback,Object)
方法能够把object对象作为参数字传送送到回调函数中。
上边例子中正是把三个string对象作为参数发送到回调函数当中。

Thread.CurrentThread.Abort(object);

1 public class Person
2 {
3 public string Name
4 {
5 get;
6 set;
7 }
8 public int Age
9 {
10 get;
11 set;
12 }
13 }
14
15 public class Message
16 {
17 public void ShowMessage(object person)
18 {
19 if (person != null)
20 {
21 Person _person = (Person)person;
22 string message = string.Format(“\n{0}’s age is {1}!\nAsync threadId
is:{2}”,
23 _person.Name,_person.Age,Thread.CurrentThread.ManagedThreadId);
24 Console.WriteLine(message);
25 }
26 for (int n = 0; n < 10; n++)
27 {
28 Thread.Sleep(300);
29 Console.WriteLine(“The number is:” + n.ToString());
30 }
31 }
32 }
33
34 class Program
35 {
36 static void Main(string[] args)
37 {
38 Console.WriteLine(“Main threadId
is:”+Thread.CurrentThread.ManagedThreadId);
39
40 Message message=new Message();
四一 //绑定带参数的异步方法
42 Thread thread = new Thread(new
ParameterizedThreadStart(message.ShowMessage));
43 Person person = new Person();
44 person.Name = “Jack”;
45 person.Age = 21;
四6 thread.Start(person); //运维异步线程
47
48 Console.WriteLine(“Do something ……….!”);
49 Console.WriteLine(“Main thread working is complete!”);
50
51 }
52 }

        static string Hello(string name)
        {
            ThreadMessage(“Async Thread”);
            Thread.Sleep(2000);
            return “\nHello ” + name;
        }

叁.陆 终止线程

        static void ThreadMessage(string data)
        {
            string message = string.Format(“{0}\n  ThreadId is:{1}”,
                   data,Thread.CurrentThread.ManagedThreadId);
            Console.WriteLine(message);
        }
    }

壹、线程的概念

BeginInvoke,调用回调函数方法  ,代码实例:

   

Thread thread = new Thread(new ParameterizedThreadStart(object));

运营结果:

        static void ThreadMessage(string data)
        {
            string message = string.Format(“{0}\n  ThreadId is:{1}”,
                   data, Thread.CurrentThread.ManagedThreadId);
            Console.WriteLine(message);
        }
    }

5、CL途乐线程池的I/O线程


以下那一个事例,便是通过Thread展现当前线程消息

class Program
    {
        delegate string MyDelegate(string name);

回去目录

            {
                Thread.Sleep(200);      //虚拟操作
                Console.WriteLine(“Main thead do work!”);
            }

1 class Program
2 {
3 delegate string MyDelegate(string name);
4
5 static void Main(string[] args)
6 {
7 ThreadMessage(“Main Thread”);
8
玖 //建立法委员会委员托
10 MyDelegate myDelegate = new MyDelegate(Hello);
1一 //异步调用委托,获取总括结果
12 IAsyncResult result=myDelegate.BeginInvoke(“Leslie”, null, null);
一3 //在异步线程未成功前实行别的干活
14 while (!result.IsCompleted)
15 {
1陆 Thread.Sleep(200); //虚拟操作
17 Console.WriteLine(“Main thead do work!”);
18 }
19 string data=myDelegate.EndInvoke(result);
20 Console.WriteLine(data);
21
22 Console.ReadKey();
23 }
24
25 static string Hello(string name)
26 {
27 ThreadMessage(“Async Thread”);
28 Thread.Sleep(2000);
29 return “Hello ” + name;
30 }
31
32 static void ThreadMessage(string data)
33 {
34 string message = string.Format(“{0}\n ThreadId is:{1}”,
35 data,Thread.CurrentThread.ManagedThreadId);
36 Console.WriteLine(message);
37 }
38 }

 ThreadPool.QueueUserWorkItem(WaitCallback)
 ThreadPool.QueueUserWorkItem(WaitCallback,Object) 

二.3 线程的保管格局

            //建立法委员会委员托
            MyDelegate myDelegate = new MyDelegate(Hello);
           
            //建立Person对象
            Person person = new Person();
            person.Name = “Elva”;
            person.Age = 27;
           
            //异步调用委托,输入参数对象person, 获取计算结果
            myDelegate.BeginInvoke(“Leslie”, new
AsyncCallback(Completed), person);           
         
            //在运行异步线程后,主线程能够继承做事而不须求拭目以俟
            for (int n = 0; n < 6; n++)
                Console.WriteLine(”  Main thread do work!”);
            Console.WriteLine(“”);

图片 10

利用委托达成劳重力线程:

二.2  System.Threading 命名空间

            //获取委托对象,调用EndInvoke方法赢得运转结果
            AsyncResult _result = (AsyncResult)result;
            MyDelegate myDelegate =
(MyDelegate)_result.AsyncDelegate;
            string data = myDelegate.EndInvoke(_result);
            //获取Person对象
            Person person = (Person)result.AsyncState;
            string message = person.Name + “‘s age is ” +
person.Age.ToString();

图片 11

异步调用委托方法,BeginInvoke
方法除最终的八个参数外,别的参数都以与艺术参数相呼应的。通过 BeginInvoke
方法将回到1个落到实处了 System.IAsyncResult
接口的指标,之后就能够使用EndInvoke(IAsyncResult )
方法就足以截止异步操作,获取委托的运作结果。

在第壹节曾经介绍过线程Thread有2特性质IsBackground,通过把此属性设置为true,就足以把线程设置为后台线程!那时应用程序域将在主线程完毕时就被卸载,而不会等待异步线程的周转。

事件注册委托,完毕播放作用

图片 12

IAsyncResult BeginInvoke(string name,AsyncCallback callback,object
state)

ParameterizedThreadStart委托与ThreadStart委托非凡相像,但ParameterizedThreadStart委托是面向带参数方法的。注意ParameterizedThreadStart
对应措施的参数为object,此参数能够为3个值对象,也足以为一个自定义对象。

暂停当前线程,抛出ThreadAbortException
非常,格外参数ExceptionState为object

   

public interface IAsyncResult
{
    object AsyncState {get;}           
//获取用户定义的靶子,它界定或包括关于异步操作的音信。
    WailHandle AsyncWaitHandle {get;}   //获取用于等待异步操作完毕的
WaitHandle。
    bool CompletedSynchronously {get;} 
//获取异步操作是或不是同步实现的指令。
    bool IsCompleted {get;}            
//获取异步操作是或不是已到位的提示。
}

图片 13

不难易行线程序控制制措施:

   

1 class Program
2 {
3 public class Person
4 {
5 public string Name;
6 public int Age;
7 }
8
9 delegate string MyDelegate(string name);
10
11 static void Main(string[] args)
12 {
13 ThreadMessage(“Main Thread”);
14
一五 //建立法委员会委员托
16 MyDelegate myDelegate = new MyDelegate(Hello);
17
18 //建立Person对象
19 Person person = new Person();
20 person.Name = “Elva”;
21 person.Age = 27;
22
二三 //异步调用委托,输入参数对象person, 获取计算结果
24 myDelegate.BeginInvoke(“Leslie”, new AsyncCallback(Completed),
person);
25
二6 //在开发银行异步线程后,主线程能够再而三工作而不供给等待
27 for (int n = 0; n < 6; n++)
28 Console.WriteLine(” Main thread do work!”);
29 Console.WriteLine(“”);
30
31 Console.ReadKey();
32 }
33
34 static string Hello(string name)
35 {
36 ThreadMessage(“Async Thread”);
37 Thread.Sleep(2000);
38 return “\nHello ” + name;
39 }
40
41 static void Completed(IAsyncResult result)
42 {
43 ThreadMessage(“Async Completed”);
44
四伍 //获取委托对象,调用EndInvoke方法取得运营结果
46 AsyncResult _result = (AsyncResult)result;
47 MyDelegate myDelegate = (MyDelegate)_result.AsyncDelegate;
48 string data = myDelegate.EndInvoke(_result);
49 //获取Person对象
50 Person person = (Person)result.AsyncState;
51 string message = person.Name + “‘s age is ” +
person.Age.ToString();
52
53 Console.WriteLine(data+”\n”+message);
54 }
55
56 static void ThreadMessage(string data)
57 {
58 string message = string.Format(“{0}\n ThreadId is:{1}”,
59 data, Thread.CurrentThread.ManagedThreadId);
60 Console.WriteLine(message);
61 }
62 }

1 class Program
2 {
3 delegate string MyDelegate(string name);
4
5 static void Main(string[] args)
6 {
7 ThreadMessage(“Main Thread”);
8
⑨ //建立法委员会委员托
10 MyDelegate myDelegate = new MyDelegate(Hello);
1一 //异步调用委托,获取计算结果
12 myDelegate.BeginInvoke(“Leslie”, new AsyncCallback(Completed),
null);
一三 //在开发银行异步线程后,主线程能够继承工作而不需求等待
14 for (int n = 0; n < 6; n++)
15 Console.WriteLine(” Main thread do work!”);
16 Console.WriteLine(“”);
17
18 Console.ReadKey();
19 }
20
21 static string Hello(string name)
22 {
23 ThreadMessage(“Async Thread”);
24 Thread.Sleep(2000); \\效仿异步操作
25 return “\nHello ” + name;
26 }
27
28 static void Completed(IAsyncResult result)
29 {
30 ThreadMessage(“Async Completed”);
31
3二 //获取委托对象,调用EndInvoke方法获得运转结果
33 AsyncResult _result = (AsyncResult)result;
34 MyDelegate myDelegate = (MyDelegate)_result.AsyncDelegate;
35 string data = myDelegate.EndInvoke(_result);
36 Console.WriteLine(data);
37 }
38
39 static void ThreadMessage(string data)
40 {
41 string message = string.Format(“{0}\n ThreadId is:{1}”,
42 data, Thread.CurrentThread.ManagedThreadId);
43 Console.WriteLine(message);
44 }
45 }

委托

说明

ContextCallback

表示要在新上下文中调用的方法。

ParameterizedThreadStart

表示在 Thread 上执行的方法。

ThreadExceptionEventHandler

表示将要处理 Application 的 ThreadException 事件的方法。

ThreadStart

表示在 Thread 上执行的方法。

TimerCallback

表示处理来自 Timer 的调用的方法。

WaitCallback

表示线程池线程要执行的回调方法。

WaitOrTimerCallback

表示当 WaitHandle 超时或终止时要调用的方法。

方法名称

说明

Abort()    

终止本线程。

GetDomain()

返回当前线程正在其中运行的当前域。

GetDomainId()

返回当前线程正在其中运行的当前域Id。

Interrupt()

中断处于 WaitSleepJoin 线程状态的线程。

Join()

已重载。 阻塞调用线程,直到某个线程终止时为止。

Resume()

继续运行已挂起的线程。

Start()  

执行本线程。

Suspend()

挂起当前线程,如果当前线程已属于挂起状态则此不起作用

Sleep()  

把正在运行的线程挂起一段时间。

图片 14

归来目录

使用程序域(AppDomain)是一个程序运维的逻辑区域,它能够视为二个轻量级的经过,.NET的次第集正是在选用程序域中运作的,叁个进程能够涵盖有几个利用程序域,多个选用程序域也可以蕴含多少个程序集。在三个施用程序域中富含了3个或多少个左右文context,使用前后文CL昂科威就能够把一些特殊对象的气象放置在分歧容器当中。

图片 15

运作结果

四.7 回调函数

   

运作结果

图片 16

四.三 通过QueueUserWorkItem运转工小编线程

属性名称

说明

CurrentContext

获取线程正在其中执行的当前上下文。

CurrentThread

获取当前正在运行的线程。

ExecutionContext

获取一个 ExecutionContext 对象,该对象包含有关当前线程的各种上下文的信息。

IsAlive

获取一个值,该值指示当前线程的执行状态。

IsBackground

获取或设置一个值,该值指示某个线程是否为后台线程。

IsThreadPoolThread

获取一个值,该值指示线程是否属于托管线程池。

ManagedThreadId

获取当前托管线程的唯一标识符。

Name

获取或设置线程的名称。

Priority

获取或设置一个值,该值指示线程的调度优先级。

ThreadState

获取一个值,该值包含当前线程的状态。

运营结果如下,此时利用程序域将在主线程运营5秒后自行终止

   

   

4.4  委托类       

   

四.5  利用BeginInvoke与EndInvoke实现异步委托方法

图片 17

   

   

通过ThreadState能够检查评定线程是高居Unstarted、Sleeping、Running
等等状态,它比 IsAlive 属质量提供越多的一定信息。

图片 18

4.6  善用IAsyncResult

贰.壹.壹 线程的标识符

按 Ctrl+C 复制代码

图片 19

   

在以上例子中能够瞥见,假如在应用myDelegate.BeginInvoke后及时调用myDelegate.EndInvoke,那在异步线程未到位工作从前主线程将处于阻塞状态,等到异步线程甘休获取总结结果后,主线程才能持续工作,这眼看力不从心体现出十二线程的优势。此时得以好好利用IAsyncResult
升高主线程的行事性质,IAsyncResult有以下成员:

图片 20

在单CPU系统的1个单位时间(time
slice)内,CPU只好运维单个线程,运营顺序取决于线程的先行级别。假如在单位时间内线程未能做到实施,系统就会把线程的处境新闻保存到线程的地面存款和储蓄器(TLS)
中,以便下次执行时上涨执行。而三十二线程只是系统带来的贰个假像,它在四个单位时间内开始展览五个线程的切换。因为切换频密而且单位时间相当的短暂,所以多线程可被作为同时运维。

3.1 使用ThreadStart委托

二、线程的基础知识

   

图片 21

图片 22

当定义委托后,.NET就会自动创立贰个意味着该信托的类,下边可以用反射情势呈现委托类的点子成员(对反射有趣味的心上人能够先参考一下”.NET基础篇——反射的微妙“)

图片 23

正文首要从线程的根底用法,CL奥迪Q伍线程池当江西中华工程公司笔者线程与I/O线程的费用,并行操作PLINQ等多个地点介绍拾二线程的支付。
在那之中央委员托的BeginInvoke方法以及回调函数最为常用。

I/O线程也许简单遭遇大家的大意,其实在付出102线程系统,更应有多留意I/O线程的操作。尤其是在ASP.NET开发在这之中,恐怕更五人只会注目的在于客户端应用Ajax或然在服务器端使用UpdatePanel。其实合情合理使用I/O线程在简报项目或文件下载时,能尽只怕地缩减IIS的下压力。
交互编制程序是Framework四.0中奋力推广的异步操作方法,更值得越来越尖锐地读书。
企望本篇小说能对各位的上学商量具有扶助,个中有所错漏的地点敬请点评。

图片 24

当调用Invoke()方法时,对应此委托的具有办法都会被执行。而BeginInvoke与EndInvoke则支持委托方法的异步调用,由BeginInvoke运转的线程都属于CL冠道线程池中的工小编线程,在下边将详细表明。

在System.Threading命名空间内提供多少个法子来创设四线程应用程序,在那之中ThreadPool与Thread是多线程开发中最常用到的,在.NET中尤其设定了3个CL福特Explorer线程池专门用来管理线程的运维,那一个CLHaval线程池便是通过ThreadPool类来治本。而Thread是治本线程的最直白格局,下边几节将详细介绍有关内容。

1 public class Message
2 {
3 public void ShowMessage()
4 {
5 string message = string.Format(“\nAsync threadId is:{0}”,
6 Thread.CurrentThread.ManagedThreadId);
7 Console.WriteLine(message);
8 for (int n = 0; n < 10; n++)
9 {
10 Thread.Sleep(300);
11 Console.WriteLine(“The number is:” + n.ToString());
12 }
13 }
14 }
15
16 class Program
17 {
18 static void Main(string[] args)
19 {
20 Console.WriteLine(“Main threadId is:”+
21 Thread.CurrentThread.ManagedThreadId);
22
23 Message message=new Message();
24 Thread thread = new Thread(new ThreadStart(message.ShowMessage));
25 thread.IsBackground = true;
26 thread.Start();
27
28 Console.WriteLine(“Do something ……….!”);
29 Console.WriteLine(“Main thread working is complete!”);
30 Console.WriteLine(“Main thread sleep!”);
31 Thread.Sleep(5000);
32 }
33 }

   

进度、应用程序域、线程的关系如下图,3个经过内可以归纳三个使用程序域,也有囊括八个线程,线程也得以不断于多少个利用程序域个中。但在同一个时刻,线程只会处于三个使用程序域内。

若想终止正在周转的线程,能够使用Abort()方法。在使用Abort()的时候,将抓住多个特种分外ThreadAbortException 。
若想在线程终止前苏醒线程的实践,能够在破获分外后
,在catch(ThreadAbortException ex){…}
中调用Thread.ResetAbort()撤除终止。
而选择Thread.Join()能够保障应用程序域等待异步线程截止后才打住运维。

4.1 关于CLR线程池

二、线程的基础知识

八、计时器与锁

3.2 使用ParameterizedThreadStart委托

通过轮询方式,使用IsCompleted属性判断异步操作是还是不是做到,那样在异步操作未到位前就足以让主线程执行别的的工作。

   

图片 25

   

图片 26

前边说过,3个行使程序域中或然包括八个上下文,而经过CurrentContext能够获取线程当前的上下文。

先是创建2个委托对象,通过IAsyncResult BeginInvoke(string
name,AsyncCallback callback,object state) 异步调用委托方法,BeginInvoke
方法除最终的三个参数外,其它参数都以与办法参数相对应的。通过 BeginInvoke
方法将再次回到多个实现了 System.IAsyncResult
接口的指标,之后就足以应用EndInvoke(IAsyncResult )
方法就能够截至异步操作,获取委托的周转结果。

使用ThreadStart与ParameterizedThreadStart建立新线程分外简单,但经过此办法创制的线程难于管理,若建立过多的线程反而会潜移默化系统的属性。
有见及此,.NET引进CL昂科雷线程池这一个定义。CLWrangler线程池并不会在CLLacrosse初步化的时候立时创设线程,而是在应用程序要创建线程来实施职分时,线程池才初始化3个线程。线程的早先化与其余的线程一样。在成功任务之后,该线程不会自行销毁,而是以挂起的动静重回到线程池。直到应用程序再次向线程池发出请求时,线程池里挂起的线程就会再一次激活执行职分。这样既省去了树立线程所造成的习性损耗,也能够让七个任务反复重用同一线程,从而在应用程序生存期内节约大批量费用。

透过ThreadStart来创建三个新线程是最直接的艺术,但诸如此类创立出来的线程相比难管理,假若成立过多的线程反而会让系统的本性下载。有见及此,.NET为线程管理越发设置了一个CL昂Cora线程池,使用CL卡宴线程池系统能够更客观地保管线程的使用。全部请求的劳务都能运作于线程池中,当运维结束时线程便会回归到线程池。通过安装,能控制线程池的最大线程数量,在呼吁超出线程最大值时,线程池能遵照操作的预先级别来实行,让有个别操作处于等候情形,待有线程回归时再实施操作。

   

图片 27

在System.Threading中的包蕴了下表中的五个常用委托,在那之中ThreadStart、ParameterizedThreadStart是最常用到的信托。
由ThreadStart生成的线程是最直白的不2秘诀,但由ThreadStart所生成并不受线程池管理。
而ParameterizedThreadStart是为异步触发带参数的办法而设的,在下一节将为我们逐一细说。

贰.壹.5 开发实例

   

1 static void Main(string[] args)
2 {
3 Thread thread = Thread.CurrentThread;
4 thread.Name = “Main Thread”;
5 string threadMessage = string.Format(“Thread ID:{0}\n Current
AppDomainId:{1}\n “+
6 “Current ContextId:{2}\n Thread Name:{3}\n “+
7 “Thread State:{4}\n Thread Priority:{5}\n”,
8 thread.ManagedThreadId, Thread.GetDomainID(),
Thread.CurrentContext.ContextID,
9 thread.Name, thread.ThreadState, thread.Priority);
10 Console.WriteLine(threadMessage);
11 Console.ReadKey();
12 }

先把WaitCallback委托指向二个暗含Object参数的无重回值方法,再采纳ThreadPool.QueueUserWorkItem(WaitCallback)
就足以异步运营此方法,此时异步方法的参数被视为null 。

图片 28

请留心运维结果,在调用Thread.Start()方法后,系统以异步格局运维Message.ShowMessage(),而主线程的操作是继续执行的,在Message.ShowMessage()完毕前,主线程已到位全数的操作。

图片 29

三、以ThreadStart格局贯彻10贰线程

若是想为回调函数字传送送1些外部消息,就足以利用BeginInvoke(AsyncCallback,object)的结尾1个参数object,它同意外部向回调函数输入任何类型的参数。只须求在回调函数中央银行使
AsyncResult.AsyncState 就足以获取object对象。

但系统不能够预言异步线程须求周转的年月,所以用经过Thread.Sleep(int)阻塞主线程并不是2个好的化解格局。有见及此,.NET专门为等待异步线程达成支付了另八个措施thread.Join()。把地方例子中的最终1行Thread.Sleep(4000)修改为
thread.Join() 就能担保主线程在异步线程thread运转停止后才会结束。

   

适度接纳十二线程能坚实系统的性质,比如:在系统请求大容量的数额时利用二十多线程,把数量输出工作付出异步线程,使主线程保持其安静去处理任何难点。但必要专注一点,因为CPU供给成本不少的时光在线程的切换上,所以众多地应用二十八线程反而会促成品质的降低。

2.1.4 System.Threading.Thread的方法

图片 30

图片 31

三.四 挂起线程

   

运作结果:

3.5 Suspend 与 Resume (慎用)

注意透过CL卡宴线程池所确立的线程总是暗中认可为后台线程,优先级数为ThreadPriority.Normal。

   

ThreadPool线程池中涵盖有七个静态方法能够一贯开发银行工我线程:
一为 ThreadPool.QueueUserWorkItem(WaitCallback)
二为 ThreadPool.QueueUserWorkItem(WaitCallback,Object) 

一、线程的定义

图片 32

   

二.一.三 线程的状态

图片 33

1 public class Message
2 {
3 public void ShowMessage()
4 {
5 string message = string.Format(“Async threadId is :{0}”,
6 Thread.CurrentThread.ManagedThreadId);
7 Console.WriteLine(message);
8
9 for (int n = 0; n < 10; n++)
10 {
11 Thread.Sleep(300);
12 Console.WriteLine(“The number is:” + n.ToString());
13 }
14 }
15 }
16
17 class Program
18 {
19 static void Main(string[] args)
20 {
21 Console.WriteLine(“Main threadId is:”+
22 Thread.CurrentThread.ManagedThreadId);
23 Message message=new Message();
24 Thread thread = new Thread(new ThreadStart(message.ShowMessage));
25 thread.Start();
26 Console.WriteLine(“Do something ……….!”);
27 Console.WriteLine(“Main thread working is complete!”);
28
29 }
30 }

 
是因为本文是以介绍三十六线程技术为宗旨,对进度、应用程序域的介绍就到此截止。关于进度、线程、应用程序域的技巧,在”C#归纳揭秘——细说进度、应用程序域与上下文“会有详实介绍。

7、并行编制程序与PLINQ

图片 34

Thread.Suspend()与 Thread.Resume()是在Framework一.0
就早已存在的老艺术了,它们分别能够挂起、恢复线程。但在Framework二.0中就曾经驾驭排斥那四个办法。那是因为假若某些线程占用了已部分能源,再使用Suspend()使线程长期处在挂起状态,当在其他线程调用这几个财富的时候就会挑起死锁!所以在并未有要求的状态下应当制止接纳那七个艺术。

图片 35

基础知识就为大家介绍到此地,上边将详细介绍四线程的支出。

   

图片 36

   

图片 37

三.三 前台线程与后台线程

图片 38

按 Ctrl+C 复制代码

图片 39

六、异步
SqlCommand

   

 一. 1 历程、应用程序域与线程的涉及

成员名称

说明

Lowest

可以将 Thread 安排在具有任何其他优先级的线程之后。

BelowNormal

可以将 Thread 安排在具有 Normal 优先级的线程之后,在具有 Lowest 优先级的线程之前。

Normal

默认选择。可以将 Thread 安排在具有 AboveNormal 优先级的线程之后,在具有BelowNormal 优先级的线程之前。

AboveNormal

可以将 Thread 安排在具有 Highest 优先级的线程之后,在具有 Normal 优先级的线程之前。

Highest

可以将 Thread 安排在具有任何其他优先级的线程之前。

因而ThreadPool.Get马克斯(out int workerThreads,out int
completionPortThreads )和 ThreadPool.Set马克斯( int workerThreads, int
completionPortThreads)四个格局能够分别读取和安装CL昂科雷线程池湖北中华工程公司小编线程与I/O线程的最大线程数。在Framework2.0中最大线程暗中同意为二5*CPU数,在Framewok3.0、4.0中最大线程数暗许为250*CPU数,在近日I3,I5,I七 CPU出现后,线程池的最大值1般私下认可为1000、3000。
若想测试线程池中有微微的线程正在投入使用,可以透过ThreadPool.GetAvailableThreads( out
int workerThreads,out int completionPortThreads ) 方法。

1 class Program
2 {
3 delegate void MyDelegate();
4
5 static void Main(string[] args)
6 {
7 MyDelegate delegate1 = new MyDelegate(AsyncThread);
八 //显示委托类的多少个点子成员
9 var methods=delegate1.GetType().GetMethods();
10 if (methods != null)
11 foreach (MethodInfo info in methods)
12 Console.WriteLine(info.Name);
13 Console.ReadKey();
14 }
15 }

1 class Program
2 {
3 static void Main(string[] args)
4 {
伍 //把CL福特Explorer线程池的最大值设置为一千
6 ThreadPool.SetMaxThreads(1000, 1000);
柒 //呈现主线程运维时线程池新闻
8 ThreadMessage(“Start”);
玖 //运行工小编线程
10 ThreadPool.QueueUserWorkItem(new WaitCallback(AsyncCallback));
11 Console.ReadKey();
12 }
13
14 static void AsyncCallback(object state)
15 {
16 Thread.Sleep(200);
17 ThreadMessage(“AsyncCallback”);
18 Console.WriteLine(“Async thread do work!”);
19 }
20
二一 //显示线程现状
22 static void ThreadMessage(string data)
23 {
24 string message = string.Format(“{0}\n CurrentThreadId is {1}”,
25 data, Thread.CurrentThread.ManagedThreadId);
26 Console.WriteLine(message);
27 }
28 }

线程(Thread)是进度中的基本举行单元,在进程入口实施的第3个线程被视为这么些进度的主线程。在.NET应用程序中,都以以Main()方法作为入口的,当调用此措施时系统就会自行创造一个主线程。线程首借使由CPU寄存器、调用栈和线程本地存款和储蓄器(Thread
Local
Storage,TLS)组成的。CPU寄存器首要记录当前所推行线程的情形,调用栈主要用于保险线程所调用到的内部存储器与数码,TLS主要用以存放线程的事态音信。

二.①.二 线程的先期级别

图片 40

.NET为线程设置了Priority属性来定义线程执行的先期级别,里面含有5个采纳,在那之中诺玛l是私下认可值。除非系统有特殊必要,不然不应有随便设置线程的优先级别。

由此ThreadPool.QueueUserWorkItem运行工小编线程即便是造福,但WaitCallback委托指向的总得是三个分包Object参数的无重回值方法,那确实是1种范围。若方法须求有重回值,或然隐含四个参数,那将多费周折。有见及此,.NET提供了另一种办法去建立工我线程,那就是信托。

1 public interface IAsyncResult
2 {
三 object AsyncState {get;}
//获取用户定义的目的,它界定或含有关于异步操作的消息。
肆 WailHandle AsyncWaitHandle {get;} //获取用于等待异步操作实现的
WaitHandle。
5 bool CompletedSynchronously {get;}
//获取异步操作是不是同步到位的提示。
陆 bool IsCompleted {get;} //获取异步操作是或不是已做到的指令。
7 }

1 class Program
2 {
3 delegate string MyDelegate(string name);
4
5 static void Main(string[] args)
6 {
7 ThreadMessage(“Main Thread”);
8
玖 //建立法委员会委员托
10 MyDelegate myDelegate = new MyDelegate(Hello);
11 //异步调用委托,获取总结结果
12 IAsyncResult result=myDelegate.BeginInvoke(“Leslie”, null, null);
1三 //达成主线程其余干活
14 ………….
1伍 //等待异步方法成功,调用EndInvoke(IAsyncResult)获取运维结果
16 string data=myDelegate.EndInvoke(result);
17 Console.WriteLine(data);
18
19 Console.ReadKey();
20 }
21
22 static string Hello(string name)
23 {
24 ThreadMessage(“Async Thread”);
25 Thread.Sleep(三千); //虚拟异步工作
26 return “Hello ” + name;
27 }
28
2玖 //展现当前线程
30 static void ThreadMessage(string data)
31 {
32 string message = string.Format(“{0}\n ThreadId is:{1}”,
33 data,Thread.CurrentThread.ManagedThreadId);
34 Console.WriteLine(message);
35 }
36 }

   

   

三、以ThreadStart方式贯彻十二线程

2.1 System.Threading.Thread类

1.2 多线程

此处先以3个事例显示一下102线程带来的好处,首先在Message类中树立几个方式ShowMessage(),里面显示了现阶段运维线程的Id,并使用Thread.Sleep(int
)
方法模拟部分工作。在main()中通过ThreadStart委托绑定Message对象的ShowMessage()方法,然后经过Thread.Start()执行异步方法。

4、CL中华V线程池的工作者线程

   

Thread
中包蕴了多少个方法来支配线程的开创、挂起、甘休、销毁,现在来的例证中会平日利用。

它回顾以下常用公共性质:

经过(Process)是Windows系统中的1个基本概念,它含有着2个运维程序所需求的资源。进度之间是相对独立的,1个历程不也许访问另三个进度的数额(除非选择分布式总计格局),一个进程运转的挫败也不会影响其余进度的运作,Windows系统正是运用进度把工作划分为多少个独立的区域的。进度可以驾驭为四个顺序的主旨边界。

System.Threading.Thread是用于控制线程的基础类,通过Thread能够控制当前利用程序域中线程的创始、挂起、甘休、销毁。

   

   

图片 41

   

1 class Program
2 {
3 static void Main(string[] args)
4 {
5 //把线程池的最大值设置为一千
6 ThreadPool.SetMaxThreads(1000, 1000);
7
8 ThreadMessage(“Start”);
9 ThreadPool.QueueUserWorkItem(new WaitCallback(AsyncCallback),”Hello
Elva”);
10 Console.ReadKey();
11 }
12
13 static void AsyncCallback(object state)
14 {
15 Thread.Sleep(200);
16 ThreadMessage(“AsyncCallback”);
17
18 string data = (string)state;
19 Console.WriteLine(“Async thread do work!\n”+data);
20 }
21
22 //呈现线程现状
23 static void ThreadMessage(string data)
24 {
25 string message = string.Format(“{0}\n CurrentThreadId is {1}”,
26 data, Thread.CurrentThread.ManagedThreadId);
27 Console.WriteLine(message);
28 }
29 }

能够看来,主线在调用BeginInvoke方法能够继续执行别的命令,而无需再伺机了,那如实比采纳轮询方式判断异步方法是或不是成功更有优势。
在异步方法执行到位后将会调用AsyncCallback所绑定的回调函数,注意一点,回调函数照旧是在异步线程中推行,那样就不会影响主线程的运作,那也选择回调函数最值得青昧的地点。
在回调函数中有1个既定的参数IAsyncResult,把IAsyncResult强制转换为AsyncResult后,就能够透过
AsyncResult.AsyncDelegate
获取原委托,再采纳EndInvoke方法赢得计算结果。
运营结果如下: