线程2.docx
- 文档编号:3514842
- 上传时间:2022-11-23
- 格式:DOCX
- 页数:15
- 大小:51.30KB
线程2.docx
《线程2.docx》由会员分享,可在线阅读,更多相关《线程2.docx(15页珍藏版)》请在冰豆网上搜索。
线程2
多线程学习笔记第二篇
前言:
这篇博客主要是在上一篇博客的基础上,重新复习了一下上一篇博客的内容,讲解了一些特殊的使用,并且使用了大量的案例来说明,主要说明了异步委托的使用和回调函数执行异步委托以及跨线程访问控件的解决方案和一个双色球的案例。
这篇文章我以代码的形式写了,里面有大量的注释,我们可以详细的研究,很高兴能和你们一起研究。
1.线程的复习
(1)多线程Thread调用委托方法的实现Demo
classProgram
{
staticvoidMain(string[]args)
{
Threadthread=newThread(newThreadStart(DemoMethod));
//设置线程参数
thread.IsBackground=true;//后台线程,常用的都是后台线程
//设置线程的名字
thread.Name="给开发人员用的";
//设置线程的优先级(只是提议)
thread.Priority=ThreadPriority.Highest;//0-31
//启动线程,只是告诉操作系统线程准备好,开始执行此线程,但是并不一定线程立即执行
thread.Start();
Thread.Sleep(3000);
Console.ReadKey();
}
privatestaticvoidDemoMethod()
{
Console.WriteLine("执行的工作线程是:
{0}",Thread.CurrentThread.ManagedThreadId);;
}
}
执行结果是:
执行的工作线程是:
10
(2)线程配合Lambda表达式的使用
staticvoidMain(string[]args)
{
//第一种写法
Threadthread=newThread(newThreadStart(()=>
{
Console.WriteLine("执行的工作线程是:
{0}",Thread.CurrentThread.ManagedThreadId);;
}));
//第二种写法
newThread(()=>
{
Console.WriteLine("执行的工作线程是:
{0}",Thread.CurrentThread.ManagedThreadId);;
}).Start();
//设置线程参数
thread.IsBackground=true;//后台线程,常用的都是后台线程
//设置线程的名字
thread.Name="给开发人员用的";
//设置线程的优先级(只是提议)
thread.Priority=ThreadPriority.Highest;//0-31
//启动线程,只是告诉操作系统线程准备好,开始执行此线程,但是并不一定线程立即执行
thread.Start();
Thread.Sleep(3000);
Console.ReadKey();
}
//执行结果是:
//执行的工作线程是:
4
//执行的工作线程是:
3
(3)带参数的线程执行
staticvoidMain(string[]args)
{
//定义带参数的线程
Threadthread=newThread(newParameterizedThreadStart(ParameterMethodDemo));
//开启线程,传递参数
thread.Start("韩迎龙");
Thread.Sleep(3000);
}
privatestaticvoidParameterMethodDemo(objectobj)
{
Console.WriteLine("执行一个带参数的线程方法:
{0}",obj);
}
//执行结果:
执行一个带参数的线程方法:
韩迎龙
(4)异步委托回调函数的使用
namespaceReviewThread
{
//定义委托
internaldelegateintAddDel(inta,intb);
classProgram
{
staticvoidMain(string[]args)
{
//定义委托变量的时候,如果是指向第一个方法,那么必须使用new关键字
AddDeldel=newAddDel(Demo);
//同步调用
//intres=del(5,3);
//异步调用,本质就是重新开启一个线程帮我们,执行委托的方法
//内部:
开启一个新的线程执行委托
IAsyncResultresult=del.BeginInvoke(2,5,null,null);
//执行主线程要干的事情
//异步委托的好处是:
不阻塞主线程
intmethodRes=del.EndInvoke(result);
Console.WriteLine(methodRes);
Console.ReadKey();
}
publicstaticintDemo(inta,intb)
{
returna+b;
}
//执行结果:
7
}
}
2.委托的异步调用:
由另一个线程执行委托的方法
(1)简单的异步委托调用Demo
namespaceAsyncDelegate
{
internaldelegateintAddDemoDel(inta,intb);
classProgram
{
staticvoidMain(string[]args)
{
Console.WriteLine("当前主线程是:
{0}",Thread.CurrentThread.ManagedThreadId);
AddDemoDeladdDemoDel=newAddDemoDel(AddDemo);
//委托的异步调用
//开始调用委托方法,自动创建一个线程并执行委托的方法
IAsyncResultresult=addDemoDel.BeginInvoke(4,5,null,null);
//得到委托的返回值
intinta=addDemoDel.EndInvoke(result);//阻塞当前主线程,只等到子线程执行完成,并返回方法的返回值之后继续执行
Console.WriteLine("主线程执行完毕,结果是"+inta);
Thread.Sleep(10000);
Console.ReadKey();
}
privatestaticintAddDemo(inta,intb)
{
Thread.Sleep(3000);
Console.WriteLine("当前执行的线程是:
{0}",Thread.CurrentThread.ManagedThreadId);
returna+b;
}
//执行结果:
//当前主线程是:
9
//当前执行的线程是:
10
//主线程执行完毕,结果是9
}
}
(2)设置一个回调函数执行异步委托
namespaceAsyncDelegate
{
internaldelegateintAddDemoDel(inta,intb);
classProgram
{
staticvoidMain(string[]args)
{
Console.WriteLine("当前主线程是:
{0}",Thread.CurrentThread.ManagedThreadId);
AddDemoDeladdDemoDel=newAddDemoDel(AddDemo);
//指定回调函数,处理的异步委托
addDemoDel.BeginInvoke(3,4,newAsyncCallback(DelCallBackFuncDemo),"韩迎龙");
Console.WriteLine("主线程执行完毕");
Console.ReadKey();
}
//定义一个委托单额回调方法
publicstaticvoidDelCallBackFuncDemo(IAsyncResultarr)
{
Console.WriteLine("回调函数执行的线程是:
{0}",Thread.CurrentThread.ManagedThreadId);
//当我们的委托方法执行完成后,会自动调用次回调函数
AsyncResultresult=(AsyncResult)arr;
Console.WriteLine("在回调方法里面获取到的传递过来的状态:
{0}",result.AsyncState);
//回调函数获取当前委托方法执行的结果
AddDemoDeldel=(AddDemoDel)result.AsyncDelegate;//将异步委托转成我们自定义的委托类型
intfunResult=del.EndInvoke(result);//获取方法的返回值
Console.WriteLine("获取到当前方法执行的结果是:
{0}",funResult);
}
privatestaticintAddDemo(inta,intb)
{
Thread.Sleep(3000);
Console.WriteLine("当前执行的线程是:
{0}",Thread.CurrentThread.ManagedThreadId);
returna+b;
}
}
}
//执行结果如图所示:
3.一个双色球变化的案例
(1)创建一个Windows窗体应用程序(Winform),起名为DoubleBallDemo,拖放一个Button控件
(2)项目Demo代码结果如下:
ViewCode?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
namespaceDoubleBallDemo
{
//定义设置标签值的委托类型
publicdelegatevoidSetLbTextDel(stringstr,Labellabel);
publicpartialclassForm1:
Form
{
List
publicboolISStop=true;//是否结束,改变Label的值
publicForm1()
{
InitializeComponent();
//设置当前的按钮的名字为开始
btnStartEnd.Text="开始";
//初始化6个Label标签
for(inti=0;i<6;i++)
{
LabellblDemo=newLabel();
lblDemo.Text="0";
lblDemo.AutoSize=true;//自动调整大小
lblDemo.Location=newPoint(10+i*50,50);//在X轴上每隔50放一个控件
//第一将当前控件放到窗体里面去
Controls.Add(lblDemo);
//往当前集合变量里面添加当前标签
listlabel.Add(lblDemo);
}
}
privatevoidbtnStartEnd_Click(objectsender,EventArgse)
{
//现在点击的是开始按钮
if(btnStartEnd.Text.Equals("开始"))
{
this.ISStop=false;
//启动一个线程,帮我们改变标签的数字
Threadthread=newThread(()=>
{
Randomrand=newRandom();
while(!
ISStop)
{
for(inti=0;i { //listlabel[i].Text=rand.Next(0,9).ToString(); //使用Invoke方法 //Invoke方法内部会沿着控件创建的路径往上找到创建此控件的线程,找到线程之后会直接使用此线程调用委托方法 //谁创建的此标签,那么就由谁调用后面传过来的委托 //标志: 标志当前的控件是
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 线程