一.FrameWork 4.0之前的线程世界
在.NET FrameWork 4.0之前,如果我们使用线程。一般有以下几种方式:
1.使用System.Threading.Thread 类,调用实例方法Start()开启一个新线程,调用Abort()方法来提前终止线程。
2.使用System.Threading.ThreadPool类,调用静态方法QueueUserWorkItem(),将方法放入线程池队列,线程池来控制调用。
3.使用BeginInvoke,EndInvoke,BeginRead,EnRead,BeginWrite,EndWrite等一系列的异步方法。
4.使用System.ComponentModel.BackgroundWorker控件,调用实例方法RunWorkerAsync(),开启一个新线程。
二.创建一个新线程时会产出哪些开销
1.线程内核对象,包含一组对线程进行描述的属性。
2.线程环境块,包含线程异常处理的链首,线程进入的每个try{}块会在链首插入一个节点,从try{}块推出时,会在链首删除该节点。
3.用户模式栈,用来存储传给方法的局部变量和实参,它还包含一个地址,指出当前方法返回知,该从什么地方继续执行。
4.内核模式栈,应用程序代码向操作系统中的一个内核模式的函数传递实参时,会使用内核模式栈。
5.DLL线程附加和线程分离通知,线程开启或者终止时,会调用进程中加载的所有DLL的DLLMain方法。
三.线程池
由于创建一个新的线程是一个昂贵的操作,所以有了线程池来维护了一个线程队列,例如常见的数据库连接池,IIS连接池等。线程池在FrameWork 4.0之前,我们可以使用ThreadPool.QueueUserWorkItem()将一个符合WaitHandle委托类型的方法加入到线程池队列中。
代码如下:
1 static void Main(string[] args)
2 {
3 Console.WriteLine("Main");
4 ThreadPool.QueueUserWorkItem((o) =>
5 {
6 Console.WriteLine(DateTime.Now);
7 });
8 Thread.Sleep(1000);
9 Console.WriteLine("Main Next...");
10 Console.Read();
11 }
为了验证线程池内的方法确实是异步的,我们在Main方法中让主线程停止1秒。测试结果确实是线程池内的方法和Main方法是异步执行的。
四.取消操作
FrameWork提供了一个取消操作的模式,这就意味着我们可以取消正在执行的操作,对于耗时的操作来说,是非常好的用户体验。为了取消一个操作,要创建一个System.Threading.CancellationTokenSource类的实例。(MSDN入口http://msdn.microsoft.com/zh-cn/library/vstudio/system.threading.cancellationtokensource.aspx
)。这个对象包含了管理和取消的所有状态,Token属性可以获取CancellationToken的实例,可以根据IsCancellationRequested属性来判断是否需要取消操作。同时,可以通Register方法注册一个在取消时调用的委托。
代码如下:
1 static void Main(string[] args)
2 {
3 CancellationTokenSource cts = new CancellationTokenSource();
4 cts.Token.Register(() => Console.WriteLine("Register"));
5 Console.WriteLine("Main");
6 ThreadPool.QueueUserWorkItem((o) =>
7 {
8 CancellationToken ct = (CancellationToken)o;
9
10 for (int i = 0; i < 100; i++)
11 {
12 //是否需要取消操作
13 if (ct.IsCancellationRequested)
14 {
15 break;
16 }
17 Console.WriteLine(DateTime.Now);
18 Thread.Sleep(100);
19 }
20
21
22 }, cts.Token);
23 Thread.Sleep(1000);
24 //取消
25 cts.Cancel();
26 Console.WriteLine("Main Next...");
27 Console.Read();
28 }
可以看到在Main方法中创建了CancellationTokenSource的实例,同时注册了一个在取消时调用的委托,并且把这个实例传给了线程池方法。在线程池方法的循环内判断是否需要取消任务,最后在Main方法内调用cts.Cancel()取消了操作。
五.Task(任务)
1.创建任务
调用ThreadPool.QueueUserWorkItem()方法来处理异步的操作是非常简单的。但是这个是有很多限制的。比如,我们不知道线程池什么时候开始执行方法,什么时候方法执行结束,而且也没有方法的返回值。所以在FrameWork 4.0里,引入了Task的概念。我们可以在 System.Threading.Tasks命名空间下找到它们(MSDN入口http://msdn.microsoft.com/zh-cn/library/vstudio/system.threading.tasks.task.aspx),可以用Task做同样的异步操作。
代码如下:
static void Main(string[] args)
{
Console.WriteLine("Main");
Task<int> task = new Task<int>(() =>
{
int sum = 0;
for (int i = 0; i <= 1000; i++)
{
Thread.Sleep(10);
sum += i;
}
return sum;
});
task.Start();
Console.WriteLine(task.Result);//获取任务的执行结果
Console.Read();
}
要注意的是调用task.Result获取返回值,或者是task.Wait()等待任务执行完成,主线程将会被阻塞。要等到Task执行完成才会继续执行。同时,如果Task内部抛出了一个未处理的异常,这个异常会在调用Result或者Wait()是时候会抛出System.AggregateException。
2.一个任务完成后自动执行一个新任务
由于调用task.Result或者task.Wait()时会阻塞,所以Task提供了一个ContinueWith()方法,有很多重载。这个方法可以在一个任务完成时,启动一个新任务,并不阻塞主线程。
代码如下:
1 static void Main(string[] args)
2 {
3 Console.WriteLine("Main");
4 Task<int> task = new Task<int>(() =>
5 {
6 int sum = 0;
7 for (int i = 0; i <= 1000; i++)
8 {
9 Thread.Sleep(10);
10 sum += i;
11 }
12
13 return sum;
14 });
15 task.Start();
16 task.ContinueWith((t) => Console.WriteLine(t.Result));//获取任务的执行结果
17 Console.WriteLine("Main Next");
18 Console.Read();
19 }
要注意的是,执行到ContinueWith的时候,可能第一个求和的任务已经完成了。不过这不影响结果,ContinueWith方法会立即启动第二个任务。
3.任务的状态
Task内部有Status的只读属性,这个的属性是TaskStatus类型的枚举。在Task对象的生存期间,可以通过Status获取任务的的当前状态。这个枚举的状态的定义如下:
1 public enum TaskStatus
2 {
3 Created = 0, //该任务已初始化,但尚未被计划
4
5 WaitingForActivation = 1, //该任务正在等待 .NET Framework 基础结构在内部将其激活并进行计划。
6
7 WaitingToRun = 2, //该任务已被计划执行,但尚未开始执行。
8
9 Running = 3, //该任务正在运行,但尚未完成。
10
11 WaitingForChildrenToComplete = 4,//该任务已完成执行,正在隐式等待附加的子任务完成。
12
13 RanToCompletion = 5, //已成功完成执行的任务。
14
15 Canceled = 6, //该任务已通过对其自身的 CancellationToken 引发 OperationCanceledException 对取消进行了确认,
16 // 此时该标记处于已发送信号状态;或者在该任务开始执行之前,已向该任务的CancellationToken 发出了信号。
17
18 Faulted = 7, // 由于未处理异常的原因而完成的任务。
19 }
在创建一个Task对象时,状态是Created。当调用Start()方法,任务启动时,状态变成了WaitingToRun(),任务真正开始执行时,状态变成了Running,任务结束时,对应的三种不同的状态:成功、被取消、执行中出现未处理异常,分别对应:RanToCompletion、Canceled、Faulted。
相关推荐
ASP.NET SignalR 是为 ASP.NET 开发人员提供的一个库,可以简化开发人员将实时 Web 功能添加到应用程序的过程。实时 Web 功能是指这样一种功能:当所连接的客户端变得可用时服务器代码可以立即向其推送内容,而不是...
总结,本教程详细介绍了如何在`.NET6 API`和`Vue`应用中集成 SignalR,包括引入 SignalR 服务、编写 Hub、配置路由、处理跨域以及在 Vue 客户端建立连接和发送/接收消息。遵循这些步骤,你就可以创建一个实时通信的...
ASP.NET SignalR是一种用于构建实时Web应用程序的强大框架,由微软开发并支持,它极大地简化了服务器到客户端的数据推送过程,从而实现了双向通信。SignalR利用多种传输方式(如WebSocket、Server-Sent Events、Long...
ASP.NET MVC与SignalR结合,提供了以下关键知识点: 1. **SignalR概念**:SignalR主要由Hubs、Connections、Groups和Transports组成。Hubs是最常用的方式,它允许服务器直接调用客户端的方法,实现双向通信。...
**Asp.net SignalR通知指定用户** 在ASP.NET框架中,SignalR是一个强大的实时通信库,它使得服务器向客户端实时推送数据变得简单高效。SignalR支持多种浏览器和服务器平台,包括.NET Framework和.NET Core,以及...
ChatApp项目的视频版本
在Vue应用中,我们可以使用官方提供的`@microsoft/signalr`库来建立与ASP.NET Core SignalR服务的连接。在Vue组件中,初始化连接,订阅服务器端的方法,并定义发送消息的函数。Vue的响应式系统可以与SignalR完美结合...
Get definitive guidance on SignalR, a new library for ASP.NET developers that simplifies the process of adding real-time web functionality to your applications. Real-time web functionality enables ...
ASP.NET MVC5与SignalR是两种强大的Web开发技术,它们结合使用可以实现高效、实时的双向通信,非常适合构建实时更新的应用,比如聊天室、协作工具或者实时数据分析平台。在这个项目中,开发者使用ASP.NET MVC5作为...
SignalR 是一个用于 ASP.NET 的库,它简化了开发者在 Web 应用程序中实现实时双向通信的过程,使得服务器可以将数据推送到客户端,而不仅仅是响应客户端的请求。 首先,让我们理解.NET Core 3.1。.NET Core 是微软...
SignalRCoreWebRTC 使用信令服务器作为 SignalR Core 与 ASP.NET Core 3.1 和 WebRTC 进行一对一音频呼叫 在 Chrome、Edge、Opera 中测试
2. **安装与配置**:在ASP.NET MVC项目中使用SignalR,首先需要通过NuGet包管理器安装`Microsoft.AspNet.SignalR`包。然后,在Global.asax.cs文件的Application_Start方法中注册SignalR路由。 3. **创建Hub类**:...
ASP.NET用SignalR建立浏览器和服务器的持久连接详解
ASP.NET Core 6.0 介绍和应用概述 ASP.NET Core 6.0 是一个跨平台的、开源的、模块化的 Web 框架,由 Microsoft 开发。它提供了一个灵活的、可扩展的框架来构建 Web 应用程序。 ASP.NET Core 6.0 支持多种开发模式...
NET的Azure SignalR服务SDK 适用于.NET的Azure SignalR Service SDK可帮助您利用可伸缩的云计算资源,利用实时消息... 您可以使用该软件包通过Azure SignalR Service直接管理ASP.NET Core SignalR客户端 .NET标准2.0
Get definitive guidance on SignalR, a new library for ASP.NET developers that simplifies the process of adding real-time web functionality to your applications. Real-time web functionality enables ...
综上所述,"asp.net mvc 版本 Signalr 即时通讯完整 Demo" 提供了一个全面的学习资源,涵盖了 SignalR 与 ASP.NET MVC 的整合、C# 编程以及实时通信的实践,对于希望掌握 Web 实时通信技术的开发者来说,这是一个...
SignalR 是 ASP.NET 团队正在开发的一个 Microsoft .NET Framework 库和 jQuery 插件,可能包括在以后版本的 ASP.NET 平台中。 winform 和 Asp.net 通信
ASP.NET支持多种实现长连接的方式,如ASP.NET SignalR和WebSocket。 二、ASP.NET SignalR SignalR是ASP.NET的一个库,专为实时Web应用程序设计,它可以轻松地处理服务器到客户端的推送更新。SignalR提供了简单易用...