SignalR介绍与Asp.net
一.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做同样的异步操作。
代码如下:
{
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。
SignalR介绍与Asp.net相关推荐
- plesk mysql nav连接_全能型空间plesk网站控制面板介绍支持ASP/ASP.NET/MSSQL/PHP/MYSQL/
本空间环境是Windows server 2008 R2+iis7+URLWRITE+ASP.NET+ASP+PHP+MYSQL+MSSQL+GZIP,全能型空间!完美支持wordpress.Z-BL ...
- 微服务介绍及Asp.net Core实战项目系列之微服务介绍
0.目录 整体架构目录:ASP.NET Core分布式项目实战-目录 一.微服务选型 在做微服务架构的技术选型的时候,以"无侵入"和"社区活跃"为主要的考量点, ...
- 介绍“Razor”— ASP.NET的一个新视图引擎
我的团队当前正在从事的工作之一就是为ASP.NET添加一个新的视图引擎. 一直以来,ASP.NET MVC都支持 "视图引擎"的概念-采用不同语法的模板的可插拔模块.当前ASP.N ...
- Asp.net SignalR 应用并实现群聊功能 开源代码
ASP.NET SignalR 是为 ASP.NET 开发人员提供的一个库,可以简化开发人员将实时 Web 功能添加到应用程序的过程.实时 Web 功能是指这样一种功能:当所连接的客户端变得可用时服务 ...
- asp.net core 中使用 signalR(二)
asp.net core 使用 signalR(二) Intro 上次介绍了 asp.net core 中使用 signalR 服务端的开发,这次总结一下web前端如何接入和使用 signalR,本文 ...
- 发现 ASP.NET Core SignalR
ASP.NET SignalR 是几年前推出的工具,可供 ASP.NET 开发人员使用,以向应用程序添加实时功能.只要基于 ASP.NET 的应用程序必须接收来自服务器(从监视系统到游戏)的频繁异步更 ...
- Asp.net Core中SignalR Core预览版的一些新特性前瞻,附源码(消息订阅与发送二进制数据)
前言 一晃一个月又过去了,上个月有个比较大的项目要验收上线.所以忙的脚不沾地.现在终于可以忙里偷闲,写一篇关于SignalR Core的文章了. 先介绍一下SignalR吧,如下: ASP.NET S ...
- asp隐藏邮箱部分字符_asp.net core 中使用 signalR(二)
asp.net core 使用 signalR(二) Intro 上次介绍了 asp.net core 中使用 signalR 服务端的开发,这次总结一下web前端如何接入和使用 signalR,本文 ...
- Asp.Net 构架(HttpModule 介绍)
Http 请求处理流程 和 Http Handler 介绍 这两篇文章里,我们首先了解了Http请求在服务器端的处理流程,随后我们知道Http请求最终会由实现了IHttpHandler接口的类进行处理 ...
最新文章
- Core Text 学习笔记-基础
- lattice diamond 3.7安装破解
- 录制声音并且播放录取的声音
- Android——监听事件总结
- 联想微型计算机功率,解锁全部潜力,联想这款笔记本可以将CPU功耗提升至24W
- mvc html绑定变量,c# – Asp.Net MVC 3使用变量对象进行自定义模型绑定
- 让自定义view宽高成比例显示
- 【题解】守望者的逃离
- 运维项目经验示例(参考)
- WIN98 当年的记忆
- C11中auto的使用
- sap ui5 中使用echarts
- Django模型层(2)
- 热搜第一!中国烟草总公司工资曝光,员工人均年收入超18万元!网友:简直是不锈钢饭碗!...
- filecoin lotus 转账fil流程和gas计算
- CANopen协议本质
- 程序员必读经典书籍 (转)
- jedispool 为redis保驾护航
- scrapy爬取优信二手车
- Java入门之基础程序设计