c#线程基础知识
大多数现代应用程序都是多线程的,并支持并发性。多线程应用程序最简单的定义是可以并发执行多个任务的应用程序。多线程应用程序的一个很好的定义是Microsoft的字处理器。多个任务正在由字处理器并行执行。例如,作者在word文档中输入。同时,拼写检查在后台运行,告知作者他输入了一个错误的拼写单词,类似的字典在后台运行。简而言之,多个任务同时完成。
在c#中,线程被用来实现并发性。线程的基本定义是:“可以独立运行的最小执行路径”。一个程序在内存中表示为一个进程,它为程序运行提供了一个隔离的环境。如果一个程序有多个线程,它们运行在进程的隔离环境中,并共享进程资源,如内存。在这种情况下,多线程很有用;例如,一个线程可以从数据库中获取记录,而另一个线程可以显示它。
实现c#线程
在c#中创建线程是一项简单的任务。系统。线程命名空间包含可用于创建线程的Thread类。如下图所示:
线程newthread = new Thread(MethodDelegate)
这里' newthread '是一个Thread类的变量。线程类的构造函数接受方法的委托(应该只传递方法名,不传递委托),该方法必须在新线程中运行。
为了运行线程,应该按以下方式在线程上调用Start方法:
newthread.Start ();
这将与调用这个start方法的方法并行地开始执行线程。换句话说,将其委托传递给newthread对象的方法将与调用Start的方法并行运行。下面的示例实际地演示了这个概念。
假设有一个方法可以显示一个简单的破折号' - '一千次。这个方法叫做DisplayDash,定义如下:
public static void DisplayDash() {for (int i = 0;我< 1000;我+ +){Console.Write(“-”);}}
为了创建一个可以与Main方法并行运行的线程,Main方法被修改如下:
public static void Main(){线程tdash = new线程(DisplayDash);tdash.Start ();For (int I = 0;我< 1000;我+ +){Console.Write(“|”);} Console.ReadLine ();}
在main方法中,使用thread类的构造函数创建了一个新线程' tdash '。委派到DisplayDash方法已经传递给构造函数。当Start在' tdash '线程上被调用时,DisplayDash方法将开始与Main方法并行执行。在main方法中,循环打印' | '符号一千次。所以,实际上会发生的是,因为两个循环在DisplayDash方法和一个在Main方法将并发执行(都在并行线程中运行),因此,CPU会定期在两个线程之间交换控制台,显示的输出会包含不规则的破折号' - '和' | '符号,如下所示:
想要学习更多关于c#和线程的知识,可以在Udemy.com上学习
c#线程加入
Join用于等待线程完成其执行,然后再移动到调用方法中的下一个语句。调用Join的方法将等待调用Join的线程ON的完成。如果Main方法中做了以下更改,Main方法将等待' tdash '线程完成它的执行,然后再执行它自己。
public static void Main(){线程tdash = new线程(DisplayDash);tdash.Start ();tdash.Join ();For (int I = 0;我< 1000;我+ +){Console.Write(“|”);} Console.ReadLine ();}
在上面的Main方法中,在Start方法下,Join方法被' tdash '线程调用,这将阻塞Main方法的进一步执行(它也在一个线程上运行,在c#中称为主线程),直到' tdash '线程完成它的执行。在控制台的输出中,第一个破折号' - '将被显示一千次,然后Main方法将显示' | '符号。这一次的输出是这样的:
向线程传递值
在前面的例子中,一个简单的无参数委托被传递给Thread构造函数,而没有参数被传递给方法。有两种方法可以将值传递给线程:
1-使用Lambda表达式与动作委托
2-使用启动方法。
- 使用Lambda表达式
假设有一个名为DisplaySymbol的方法,它显示传递给它的字符串类型符号。DisplaySymbol的定义如下:
public static void DisplaySymbol(string s) {for (int i = 0;我< 1000;我+ +){Console.Write(年代);}}
为了从Main方法中使用参数调用这个方法,可以在Main方法中使用以下代码:
线程tdash = new线程(()=> DisplaySymbol(“#”));tdash.Start ();For (int I = 0;我< 1000;我+ +){Console.Write(“|”);} Console.ReadLine ();
这里,在main方法的构造函数中,一个lambda表达式被用来用参数字符串“#”调用Action委托DisplaySymbol。在此之后,Main方法中的循环显示“|”符号。由于主线程和tdash线程的并发性,输出同样是“#”和“|”的不规则模式。
- 使用Start方法
启动方法只能用于向方法传递单个参数。为了在Start方法中传递值,DisplaySymbol方法的参数类型必须是对象,并且它应该只包含一个参数。DisplaySymbol方法可以从上一个方法修改如下:
public static void DisplaySymbol(对象s) {string symbol = s.ToString();For (int I = 0;我< 1000;我+ +){Console.Write(年代);}}
在main方法中,参数可以通过Start方法传递,如下所示:
线程tdash = new线程(DisplaySymbol);tdash.Start(“#”);For (int I = 0;我< 1000;我+ +){Console.Write(“|”);} Console.ReadLine ();
使用Start方法传递值有两个缺点:首先,只能通过Start方法传递一个参数。其次,在本例中,被调用方法中的对象参数必须转换为相应的字符串类型。