什么事asp.net异步操作,aspnetmvc异步
内容导航:
一、怎么实现NET网站异步处理
在架构领域,我们经常听见别人说“异步”,另外大家在面试中也经常会遇到这方面的问题。
什么是异步?
说到.NET异步,先来说几个比较容易混淆的概念:
1、多线程:一般指同一进程中多个线程协作运行。在多核计算机中多个线程将有机会同时运行于多个核上,如果线程中进行的是计算,则行成并行计算。
2、并行:一般指并行计算,是说同一时刻有多条指令同时被执行,这些指令可能执行于同一CPU的多核上,或者多个CPU上,或者多个物理主机甚至多个网络中。
3、异步:与同步相对应,是指呼叫另一操作后,不等待其结果,继续执行之后的操作,若之后没有其他操作,当前线程将进入睡眠状态,而CPU时间将有机会切至其他线程。在异步操作完成后通过回调函数的方式获取通知与结果。
在Web中为什么要使用异步?
在 web 应用程序看到大量在启动时的并发请求或具有突发负载 (其中会增加并发情况突然),进行异步 web 服务调用将增加你的应用程序的响应能力。
异步请求采用相同量的时间来处理与同步请求。
例如,如果某个请求生成 web 服务调用,则需要两秒钟来完成,请求所执行的两秒内是否执行同步或异步。
但是,在异步调用,线程则无需必须等待第一个请求完成时响应其他请求。 因此,异步请求可以防止出现请求排队和线程池增长时有许多并发请求调用长时间运行的操作。
异步的实现方式
异步的实现方式有多种,比如多线程。多线程将异步操作放入另一线程中运行,通过轮询或回调方法得到完成通知。
多线程实现异步调用可以采用传统的Thread类来实现,Task来实现以及 async/await 关键字实现。
对于Thread来说,当多个异步方法需要协助时,代码将显得十分复杂,为此我们需要一个更好的异步模型,从.NET4开始,引入了新的异步模型。下面来看一段代码:
我们不再关心任务如何去开始,何时会结束,一切变成了一些有关或无关的任务。
对于封装一个由多个异步方法组合成的异步方法,
组合异步方法调用后,按顺序调用第一个异步方法,紧接着,产生需要的结果Task后返回。异步方法完成时回调指定的方法,并按顺序继续调用,所有方法完成后,把运行的最终结果设置给结果Task,那么整个任务即完成。
如果异步方法有返回值,那么组合的异步方法看上去会复杂一点。类似下图所示:
为了解决这个问题,微软提供了一个非常好用的语法糖:async/await 关键字。下面我们来看一段代码:
他几乎和同步方法书写一致,代码量也比较少,程序的逻辑也很清晰,当然可读性更强。
总结
关于.NET网站异步处理分享到这里,这里做个总结:
1、.NET网站异步处理可以采用3中方式实现:Thread,Task,async/await;
2、Task出现是为了Thread的不足,async/await出现也是为了弥补Task的不足。大家有没有发现这个关系就像一条线一样。其实说到底这些都是多线程技术,底层都是Thread实现,只不过微软为了代码的可读性以及逻辑的清晰性,做了语法糖,从而更加方便开发人员使用。
3、在C#5中,添加了 async/await 关键字,使得上面遗留的问题得以解决,而且重点是,用起来非常简单!
4、NET Framework 4 引入了异步编程概念, 4.5 支持任务, 于是就有了async/await 。
以上就是我的观点,对于这个问题大家是怎么看待的呢?欢迎在下方评论区交流 ~ 我是科技领域创作者,十年互联网从业经验,欢迎关注我了解更多科技知识!
二、aspnet 什么是异步请求
中你可以通过继承IHttpHandler这个接口来实现一个同步(Synchronous)处理用户请求的类。比如你希望对于一切类型为fakephp的请求都通过你的Http
Hanlder来处理,你可以实现以下这个类:using System;using ;public class FakePHPHttpHandler :
IHttpHandler { public void ProcessRequest(HttpContext context) { //let’s
pretend we can handle PHP stuff } public bool IsReusable { get { return true;
} }}然后通过在IIS里将你的dll注册为.fakephp的handler就可以了。这些在以下的MSDN文档里都有介绍:/en-
us/library/这里想说的是如何实现一个异步(Asynchronous)d的HTTP
Handler。说起来其实也简单,只要实现IHttpAsyncHandler这个接口就好了。IHttpAsyncHandler有两个method:
BeginProcessRequestInitiates an asynchronous call to the HTTP handler.
EndProcessRequestProvides an asynchronous process End method when the process
ends. 这显然是和.NET Framework中标准的Asynchronous Programming Model (或者叫“异步模式”,
Asynchronous Pattern)是一致的:参考: Asynchronous Programming Overview异步模式的优势是的worker
thread不会等待BeginProcessRequest返回而是会掉头去接收其他的用户请求(当然你也可以要求worker
thread等待,不过这样就等于变成了Synchronous Handler)。因为通常处理一个web
request的后台时间需要比较长。假设你每秒只能处理10个用户请求,在同步模式下如果有11个人同时访问你的服务,就有一个人会看到500 Internal
Server Error之类的错误消息了。但如果是异步模式,worker
thread只要调用BeginProcessRequest,而根据Asynchronous Programming
Overview,BeginProcessRequest应该立刻返回(“立刻”的含义是它不应该进行长时间的操作,而应该调用QueueUserWorkItem之类的API将耗时的任务放到新线程里执行),这样worker
thread就可以腾出手去接收下一个user request了。注:的max worker thread上限可以通过processModel
configuration element里的maxWorkerThreads属性来改变(参考:Improving Performance 以及
processModel element),但最大的值也只是100 (range from 5 to 100, default
20)。由此引出的问题自然是:当异步操作完成时, 是如何知道并做相应处理的。这有一下几种选择:1)
当调用BeginProcessRequest的时候,可以同时传入一个AsyncCallback的delegate,而在你完成异步操作后,你应该调用这个回调函数来通知。2)
可以不停地查看IAsyncResult
(这个是BeginProcessRequest的返回值)IsCompleted属性来确认异步操作是否已经完成了,当然,当你完成异步操作时,你有义务将IsCompleted设成true。3)
也可以等待AsyncWaitHandle的信号,AsyncWaitHandle是IAsyncResult的另一个属性,这个和经典的Win32里waiting
on kernel object是类似的。4) 可以直接调用EndProcessRequest。注意:3) 和 4) 是Asynchronous
Programming Overview里规定的标准的blocking
execution的方式,也就是说,如果你的主线程在异步操作完成前无法再做任何工作时,它可以通过3) 或者
4)来等待异步操作的完成。从理论上来说,你应该保证你的IHttpAsyncHandler能满足以上所有4种方式。但现实中,你未必一定如此做。那么哪些是我们必须实现以匹配的要求的呢?或者究竟是如何实现异步调用及返回的呢?事实上,采用了方法1,也就是说,在调用BeignProcessRequest的时候,传入了一个AsyncCallback,而你应该在完成异步操作后调用这个callback,而在这个AsyncCallback里,又调用了你的EndProcessRequest来做收尾工作。根据上面的讨论,我们可以如下设计我们的Asynchronous
Http Hanlder:public class AsyncFakePHPHttpHandler : IHttpAsyncHandler {
private void ProcessRequestCallback(object state) { AsyncResult async =
(AsyncResult)state; // this is where the real work is done ProcessRequest();
ed = true; if (null != back) back(async); } public IAsyncResult
BeginProcessRequest(HttpContext context, AsyncCallback asyncCallback, object
state) { AsyncResult async = new AsyncResult(context, asyncCallback, state);
// if the callback is null, we can return immediately and let
EndProcessRequest do all the job // if callback is not null, we will use our
thread pool to execute the necessary asynchronous operations // what happens
in is that the callback in NOT null, so QueueUserWorkItem will be used if
(null != back) WorkItem(ProcessRequestCallback, async); return async; } //
this design also satisfies method 4), we implement it this way to follow the
Asynchronous Pattern as much as we can public void
EndProcessRequest(IAsyncResult result) { AsyncResult async =
(AsyncResult)result; if (null == back) ProcessRequest(); }总结一下实现异步Http
Handler的要点:1)
所有在BeginProcessRequest中的耗时操作(比如IO什么的)都应该采用异步调用(比如BeginRead/EndRead)或者生成新的线程去执行。不错,你可以设计一个blocking
BeginProcessRequest,没有人能阻止你这么做。But that’s a BAD BAD idea.2)
实现BeginProcessRequest/EndProcessRequest的目的是允许来异步调用你的Http Handler3)
你应该创建一个实现IAsyncResult接口的类,在BeginProcessRequest中你会生成一个该类的实例并返回给(注意BeginProcessRequest的返回值类型)。而根据Asynchronous
Pattern,在调用EndProcessRequest的时候会把这个实例再传回给你,你可以用这个实例来判断你所执行的任务的当前状态。4)
我个人感觉比较容易导致困惑的是这里“两段式”的异步调用操作。首先是通过BeginProcessRequest/EndProcessRequest来异步调用我们的Http
Handler的。然后我们在BeginProcessRequest又再次用异步模式(用QueueUserWorkItem或者其他的Begin/End操作)去完成真正的工作。实际上第二步的异步调用才是真正生成另一个thread来处理工作的地方。调用我们的BeginProcessRequest只是一种形式上的协议通知,因为是我们告诉:Hey,我是一个异步的handler。说:那好吧,既然你这么说的,我就用你异步的接口来调用你。事实上,在HttpRuntime的源代码中,可以看到的操作如下:
if (app is IHttpAsyncHandler) { // asynchronous handler IHttpAsyncHandler
asyncHandler = (IHttpAsyncHandler)app; andler = asyncHandler;
essRequest(context, _handlerCompletionCallback, context); } else { //
synchronous handler quest(context); FinishRequest(uest, context, null);
}====================================================================最后的题外话,关于IIS/处理请求的工作流也是一个很有趣的问题,下面的这篇文章很棒(but
the author’s English writing kinda sucks, : )
)。比如,从中我们可以知道,整个流程中其实牵涉了两个Queue,一个是Kernel mode下的,一个是User
mode下的,而后者就是所使用的Application Queue,而的worker thread就是从这个Queue里去取下一个需要处理的请求的。
三、 什么是异步请求
“异步”请求是相对于”同步”请求而言的,很多操作都存在”异步”和”同步”一说, “同步”
的意思是说,你发起一个操作,程序需要一直等待,直到操作完成,程序才能继续执行进行下一步。
异步就是 你开始一个操作,程序在操作完成之前可以继续后续的工作,当操作完成后,触发事件或者使用回调来处理操作完成的手续。
一般来说异步操作都是启动一个新的线程去处理你的请求,完成之后调用你指定的回调函数来完成整个异步操作。
中你可以通过继承IHttpHandler这个接口来实现一个同步(Synchronous)处理用户请求的类。
比如你希望对于一切类型为fakephp的请求都通过你的Http Hanlder来处理,你可以实现以下这个类:using System;using
;public class FakePHPHttpHandler : IHttpHandler { public void
ProcessRequest(HttpContext context) { //let’s pretend we can handle PHP stuff
} public bool IsReusable { get { return true; }
}}然后通过在IIS里将你的dll注册为.fakephp的handler就可以了。
这些在以下的MSDN文档里都有介绍:/en-us/library/这里想说的是如何实现一个异步(Asynchronous)d的HTTP Handler。
说起来其实也简单,只要实现IHttpAsyncHandler这个接口就好了。
IHttpAsyncHandler有两个method: BeginProcessRequestInitiates an asynchronous call
to the HTTP handler. EndProcessRequestProvides an asynchronous process End
method when the process ends. 这显然是和.NET Framework中标准的Asynchronous Programming
Model (或者叫“异步模式”, Asynchronous Pattern)是一致的:参考: Asynchronous Programming
Overview异步模式的优势是的worker
thread不会等待BeginProcessRequest返回而是会掉头去接收其他的用户请求(当然你也可以要求worker
thread等待,不过这样就等于变成了Synchronous Handler)。
因为通常处理一个web request的后台时间需要比较长。
假设你每秒只能处理10个用户请求,在同步模式下如果有11个人同时访问你的服务,就有一个人会看到500 Internal Server
Error之类的错误消息了。
但如果是异步模式,worker thread只要调用BeginProcessRequest,而根据Asynchronous Programming
Overview,BeginProcessRequest应该立刻返回(“立刻”的含义是它不应该进行长时间的操作,而应该调用QueueUserWorkItem之类的API将耗时的任务放到新线程里执行),这样worker
thread就可以腾出手去接收下一个user request了。
注:的max worker thread上限可以通过processModel configuration
element里的maxWorkerThreads属性来改变(参考:Improving Performance 以及 processModel
element),但最大的值也只是100 (range from 5 to 100, default 20)。
由此引出的问题自然是:当异步操作完成时, 是如何知道并做相应处理的。
这有一下几种选择:1)
当调用BeginProcessRequest的时候,可以同时传入一个AsyncCallback的delegate,而在你完成异步操作后,你应该调用这个回调函数来通知。
2) 可以不停地查看IAsyncResult
(这个是BeginProcessRequest的返回值)IsCompleted属性来确认异步操作是否已经完成了,当然,当你完成异步操作时,你有义务将IsCompleted设成true。
3)
也可以等待AsyncWaitHandle的信号,AsyncWaitHandle是IAsyncResult的另一个属性,这个和经典的Win32里waiting
on kernel object是类似的。
4) 可以直接调用EndProcessRequest。
注意:3) 和 4) 是Asynchronous Programming Overview里规定的标准的blocking
execution的方式,也就是说,如果你的主线程在异步操作完成前无法再做任何工作时,它可以通过3) 或者 4)来等待异步操作的完成。
从理论上来说,你应该保证你的IHttpAsyncHandler能满足以上所有4种方式。
但现实中,你未必一定如此做。
那么哪些是我们必须实现以匹配的要求的呢?或者究竟是如何实现异步调用及返回的呢?事实上,采用了方法1,也就是说,在调用BeignProcessRequest的时候,传入了一个AsyncCallback,而你应该在完成异步操作后调用这个callback,而在这个AsyncCallback里,又调用了你的EndProcessRequest来做收尾工作。
根据上面的讨论,我们可以如下设计我们的Asynchronous Http Hanlder:public class
AsyncFakePHPHttpHandler : IHttpAsyncHandler { private void
ProcessRequestCallback(object state) { AsyncResult async = (AsyncResult)state;
// this is where the real work is done ProcessRequest(); ed = true; if (null
!= back) back(async); } public IAsyncResult BeginProcessRequest(HttpContext
context, AsyncCallback asyncCallback, object state) { AsyncResult async = new
AsyncResult(context, asyncCallback, state); // if the callback is null, we can
return immediately and let EndProcessRequest do all the job // if callback is
not null, we will use our thread pool to execute the necessary asynchronous
operations // what happens in is that the callback in NOT null, so
QueueUserWorkItem will be used if (null != back)
WorkItem(ProcessRequestCallback, async); return async; } // this design also
satisfies method 4), we implement it this way to follow the Asynchronous
Pattern as much as we can public void EndProcessRequest(IAsyncResult result) {
AsyncResult async = (AsyncResult)result; if (null == back) ProcessRequest();
}总结一下实现异步Http Handler的要点:1)
所有在BeginProcessRequest中的耗时操作(比如IO什么的)都应该采用异步调用(比如BeginRead/EndRead)或者生成新的线程去执行。
不错,你可以设计一个blocking BeginProcessRequest,没有人能阻止你这么做。
But that’s a BAD BAD idea.2)
实现BeginProcessRequest/EndProcessRequest的目的是允许来异步调用你的Http Handler3)
你应该创建一个实现IAsyncResult接口的类,在BeginProcessRequest中你会生成一个该类的实例并返回给(注意BeginProcessRequest的返回值类型)。
而根据Asynchronous
Pattern,在调用EndProcessRequest的时候会把这个实例再传回给你,你可以用这个实例来判断你所执行的任务的当前状态。
4) 我个人感觉比较容易导致困惑的是这里“两段式”的异步调用操作。
首先是通过BeginProcessRequest/EndProcessRequest来异步调用我们的Http Handler的。
然后我们在BeginProcessRequest又再次用异步模式(用QueueUserWorkItem或者其他的Begin/End操作)去完成真正的工作。
实际上第二步的异步调用才是真正生成另一个thread来处理工作的地方。
调用我们的BeginProcessRequest只是一种形式上的协议通知,因为是我们告诉:Hey,我是一个异步的handler。
说:那好吧,既然你这么说的,我就用你异步的接口来调用你。
事实上,在HttpRuntime的源代码中,可以看到的操作如下: if (app is IHttpAsyncHandler) { //
asynchronous handler IHttpAsyncHandler asyncHandler = (IHttpAsyncHandler)app;
andler = asyncHandler; essRequest(context, _handlerCompletionCallback,
context); } else { // synchronous handler quest(context); FinishRequest(uest,
context, null);
}====================================================================最后的题外话,关于IIS/处理请求的工作流也是一个很有趣的问题,下面的这篇文章很棒(but
the author’s English writing kinda sucks, : ) )。
比如,从中我们可以知道,整个流程中其实牵涉了两个Queue,一个是Kernel mode下的,一个是User
mode下的,而后者就是所使用的Application Queue,而的worker thread就是从这个Queue里去取下一个需要处理的请求的。
没有分啊???
ajax的核心是客户端的javascript程序能够实现异步执行,异步执行是相对与同步执行的.同步执行意味着代码必须顺序执行,在此给你举个例子,你就会明白了!
line_1 line_2 line_3
line_1必须执行完后,才能执行line__1可能调用的是一个函数,有可能这个函数很复杂,需要运行几小时能才运算完毕,而这个时候,你必须等,等到line_1完全执行完毕,你才能执行line_2,同理,line_3也是!
异步则不同,还是假定line_1,要调用的函数要执行几个小时,而这个时候,你就不必要等line_1执行完毕才去执行line_2,同理,line_3也是!
异步执行中有一个非常特殊的功能,那就是回调.同样是上面的那个例子,line_1在调用函数时可以指定函数执行完后要调用的另一个函数.当过了几个小时后,函数执行完毕了(当然这中意也有可能会出现错误),它会发出一个回调命令,这个命令会调用指定的另一个函数,从而通知程序”执行完了”.如果可以,还会传递一些参数,这些参数可能就是几个小时以来运算的结果!
不知道我这样讲你有没有明白!至于ajax怎么用,如何去解决ajax出现的问题(比如书签问题,后退按钮的问题等),你可以自己去找这方面的资料看看.如果有什么不懂的地方,我们可以一起探讨,共同进步!
四、netframework40和45有什么区别
核心新功能和改进包括支持64位平台上大于2GB的数组。可以限制正则表达式引擎在超时之前持续尝试解析正则表达式的时间Zip压缩改进,可减少压缩文件的大小在.NETFramework4.5中,已将新的异步功能添加到C#和VisualBasic语言中。这些功能将添加用于执行异步操作的基于任务的模型。若.NETFramework4.5提供了针对并行计算的多项新功能和改进功能。4.5和4.5.1为Web窗体、WebSocket支持、异步处理程序、性能增强和许多其他功能添加了模型绑定。.NETFramework4.5提供了一个用于HTTP应用程序的新编程接口。增加了和命名空间。在.NETFramework4.5中,已添加以下功能,以便更轻松地编写和维护WindowsCommunicationFoundation(WCF)应用程序总之,.NET4.5只是对.NET4.0细节的优化和改进。4.5兼容4.0
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,请发送邮件至 55@qq.com 举报,一经查实,本站将立刻删除。转转请注明出处:https://www.szhjjp.com/n/124623.html