C# 线程、任务和同步

C# 线程、任务和同步

  • 线程、任务和同步
    • 线程概述
    • 异步委托

线程、任务和同步

使用线程有几个原因。假设从应用程序中进行网络调用需要一定的时间。用户不希望分割用户界,并且让用户一直等待直到从服务器返回一个响应为止。用户可以同时执行其他一些操作,或者甚至取消发送给服务器的请求。这些都可以使用线程来实现。

对于所有需要等待的操作,例如,因为文件、数据库或网络访问都需要一定的时间,此时就可以启动一个新线程,同时完成其他任务。即使是处理密集型的任务,线程也是有帮助的。一个进程的多个线程可以同时运行在不同的CPU上,或多核CPU的不同内核上。

还必须注意运行多个线程时的一些问题。它们可以同时运行,但如果线程访问相同的数据,就很容易出问题。必须实现同步机制。

线程概述

线程是程序中独立的指令流。使用C#编写任务程序时,都有一个入口点:Main()方法。程序从Main()方法的第一条语句开始执行,直到这个方法返回为止。

这种程序结构非常适合于其中有一个可识别的任务序列的程序,但程序常常需要同时完成多个任务。线程对客户端和服务器端应用。在Visual Studio编辑器中输入C#代码时,系统会分析代码,用下划线标出遗漏的分号或其他语法错误,这用一个后台线程完成。Microsoft Word的拼写检查器也会做相同的事。一个线程等待用户输入,而另一个线程进行后台搜索。第3个线程将写入的数据存储在临时文件中,第4个线程从Internet上下载其他数据。

运行在服务器上的应用程序中,等待客户请求的线程,称为侦听器线程。只要接收到请求,就把它传递给另一个工作线程,之后继续与客户通信。侦听器线程会立即返回,接收下一个客户发送的下一个请求。

进程包含资源,如Window句柄、文件系统句柄或其他内核对象。每个进程都分配了虚拟内存。一个进程至少包含一个线程。操作系统会调度线程。线程有一个优先级、实际上正在处理的程序的位置计数器、一个存储其局部变量的栈。每个线程都有自己的栈,但程序代码的内存和堆由一个进程的所有线程共享。这使一个进程的所有线程之间的通信非常快——该进程的所有线程都寻址相同的虚拟内存。但是这也使处理比较困难,因为多个线程可以修改同一个内存位置。

进程管理的资源包括虚拟内存和Window句柄,其中至少包含一个线程。线程时运行程序所必需的。

异步委托

创建线程的一种简单方式是定义一个委托,并异步调用它。委托是方法的类型安全的引用。Delegate类还支持异步地调用方法。在后台,Delegate类会创建一个执行任务的线程。

委托使用线程池来完成异步任务。

为了说明委托的异步特性,从一个需要一定的时间才能执行完毕的方法开始。TakesAWhile()方法至少需要经过第2个变量传递的毫秒数才能执行完,因为它调用Thread.Sleep()方法。

static int TakeAWhile(int data, int ms)	
{
	Console.WriteLine("TakeAWhile started");
	Thread.Sleep(ms);
	Console.WriteLine("TakeAWhile completed");
	return ++data;
}

要从委托中调用这个方法,必须定义一个有相同参数和返回类型的委托,如下面的TakeAWhileDelegate()方法所示:

public delegate int TakesAWhileDelegate(int data, int ms);

现在可以使用不同的技术异步地调用委托,并返回结果。

你可能感兴趣的:(C#,多线程,多线程,c#)