大雀软件园

首页 软件下载 安卓市场 苹果市场 电脑游戏 安卓游戏 文章资讯 驱动下载
技术开发 网页设计 图形图象 数据库 网络媒体 网络安全 站长CLUB 操作系统 媒体动画 安卓相关
当前位置: 首页 -> 技术开发 -> NET专区 -> VB.NET中使用代表对方法异步调用

VB.NET中使用代表对方法异步调用

时间: 2021-07-31 作者:daque

依照咱们惯例的思想办法,计划机该当是干完一件事,而后再干下一件。用术语来说,这种实行工作的办法叫作同步实行(synchronous execution)。既是如许,那么干什么要引入异步实行的观念呢? 目次 干什么要运用异步伐用实行异步伐用的办法和机理 干什么要运用异步伐用(asynchronous method execution) 依照咱们惯例的思想办法,计划机该当是干完一件事,而后再干下一件。用术语来说,这种实行工作的办法叫作同步实行(synchronous execution)。既是如许,那么干什么要引入异步实行的观念呢?因为很大略,由于同步实行在有些情景下功效不理念,不许实行咱们预期的手段。举两个大略的例子来证明一下这个题目。 a. 一个存户端步调(client side program)要从后盾数据库取回一个搀杂的数据汇合。大概这个数据库操纵自己很费时,也大概是搜集传输的数度比拟慢,总之这个本领挪用大概要花20秒功夫。即使运用同步伐用,那么在数据库截止归来之前,用户必需细心等候,什么也不许做。这功夫你大概会蓄意这个挪用渐渐的在别处举行,步调赶快归来好让你做其它的处事。等什么功夫数据归来了,在举行其随后相映的操纵。这种景象下,你就须要对数据库操纵的本领举行异步伐用。 b.一个网上粮票查问订阅步调。当存户要查问从北京到芝加哥的一切粮票的功夫,这个步调大概要在后盾经过web service对美利坚合众国西北宇航公司,华夏国际宇航公司和东方宇航公司举行考察。将那些公司的粮票情景汇中国人民解放军总后勤部一道以html的情势归来给用户。即使是同步伐用,那么须要一个接一个举行web service挪用。即使每个挪用耗费10秒钟的话,那么所有进程就要30秒钟。即使你运用异步伐用,那么你不妨在同简直一功夫就对三个公司发出相映的乞求,10秒后当截止从三个各别的网站返回顾后,你就不妨汇总并归来各用户了。如许,所有进程只须要10秒安排。 看到这边你大概会说,这个题目没什么陈腐的。我在c++,java里都不妨用线程(thread)来到达如许的功效。简直,大普遍的高档谈话都承诺你创造新的线程来细工实行如许的挪用。然而那些细工操纵比拟搀杂,步调员须要本人遏制线程的创造,废弃,融合之类很多详细处事,简单爆发缺点。而且在巨型的效劳器端的步调中,细工遏制线程偶尔本能不够优化,不许按照暂时简直效劳器的处置器情景来动静的和智能的优化线程的数目。鉴于这个因为,.net创造了一种对立大略的异步本领挪用体制,使这一题目变得越发大略。这即是即日要谈的运用代办(delegates)对本领举行异步伐用。(正文以vb.net来举行演示,c#的异步伐用和此一致,就不复给出例程了) 实行异步伐用的办法和机理 假如有如许一个本领(method),它接收一个班级的称呼,而后查问数据库,归来这个班级一切同窗的名单。 class democlass public shared function getstudentslist(classname as string) as string()'查问数据库'其它操纵 end functionend class即使对如许一个本领举行异步伐用的话,那么你开始须要设置一个有同样本领出面(function signature)的代办(delegate),比方 delegate function getstudentlistdelegate (classname as string) as string()下一步,你须要天生一个代办范例(instance),而后将这个代办和你的真实的本领“绑缚”起来,如 dim delegate as getstudentlistdelegategetstudentlistdelegate = addressof democlass.getstudentslist(为了大略起见,这边运用了静态本领,这本来不是必需的) 当你做到这步的功夫,.net的编写翻译器在后盾为你的代办减少了几个本领,它们是invoke, begininvoke, endinvoke. 即使你运用invoke本领,那么其功效是同步伐用,比方 delegate.invoke("class90")在这种情景下,代办将输出参数"class90"传播给本领getstudentslist,而后将这个本领的归来值归来给用户。这种运用本领是同步的,不是咱们所憧憬的。即使要到达异步功效,咱们要运用begininvoke和endinvoke。 让咱们先看看begininvoke 你的运用本领大概如次所示: dim ar as system. iasyncresultar = delegate.begininvoke("class90",nothing, nothing)你大概会创造,这种挪用本领有些各别。开始是多出两个输出参数,其次是归来值是system. iasyncresult。这究竟是如何一回事呢? 当你挪用begininvoke的功夫,一系列的工作在后盾机动爆发了。 当你用代办发出挪用乞求后,clr(大众谈话运转情况,common language runtime)接到这个乞求,并将这个乞求安置到一个里面的处置部队(queue)中去。一旦安置实行后,clr赶快就给挪用者归来一个iasyncresult的东西。这个东西很要害,咱们片刻还要证明他的简直效率。 当挪用者收到归来的iasyncresult东西后,它就不妨举行下一步的处事。因为将乞求安置到部队中是个特殊赶快的操纵,以是挪用者赶快就不妨去实行下一个举措,没有被“遏制(block)”。 clr在后盾保护着一个“线程池(thread pool)”。那些线程等待着前方提到的谁人处置部队。一旦有工作被安置到部队中,一个线程就会拿到这个工作并实行它。也即是说从来要挪用者线程实行的费时的操纵被线程池中的一个线程代庖了。(这边你不妨看出,尽管是用怎么办的谈话,在异步伐用中,确定有其它的线程展示。大概是你细工创造它(如java),大概是体例为你创造(如.net)。那么这个“线程池”中毕竟有几个线程呢?这个题目你不妨不必关怀。clr会按照步调的特性以及暂时的硬件前提自行确定。比方对于运转在单处置器平台上的普遍的桌面步调,这个线程池大概有几个线程;而对于一个运转在4处置器效劳器上的后盾运用,线程池大概会有近百个线程。如许做的长处即是贬低步调员的开拓难度,让.net的clr去处置那些和用户运用论理无干的题目。) 既是有线程池的线程包办实行了谁人本领挪用(getstudentslist),那么咱们如何领会后盾的这个挪用什么功夫实行呢?这个本领挪用归来的值(这边是一串弟子名单)咱们如何拿到呢?这边咱们就要用到前方提到的谁人归来的iasyncresult东西了。 这个iasyncresult东西一个“收条”似的,经过它你不妨查问后盾挪用能否实行。即使仍旧实行,你不妨经过它来取回你想要的截止。 dim ar as system.iasyncresultar = delegate.begininvoke("class90",nothing, nothing)'*** 其它少许操纵。。。'*** 查看后盾挪用状况if (ar.iscompleted) then '*** 取回异步伐用本领的截止end if即使后盾挪用仍旧中断,那么你就不妨用代办的endinvoke来获得归来值。 dim students as string()students = delegate.endinvoke(ar)那么,即使你没有尝试后盾挪用能否中断而径直运用endinvoke,那成果会如何样呢?即使后盾挪用没有实行,endinvoke挪用就会被“遏制”,直到后盾挪用实行后才归来。即使后盾挪用展示特殊,那么endinvoke还不妨捕获到这个特殊 dim students as string()trystudents = delegate.endinvoke(ar)catch ex as exception'处置这个特殊end try既是endinvoke挪用就会被“遏制”(即使后盾异步伐用还没有实行),那么底下这种标较搀杂情景clr是还好吗处置的呢? dim ar1, ar2 as system.iasyncresultdim rt1, rt2 as string()ar1 = delegate1.begininvoke("class90",nothing, nothing)ar2 = delegate2.begininvoke("class94",nothing, nothing)rt1 = delegate1.endinvoke(ar1)rt2 = delegate2.endinvoke(ar2)在这个例子中,delegate1的挪用和delegate2的挪用实行程序大概会有多种情景。比方delegate2的挪用后发先至,那么endinvoke的运用程序是否很要害呢?究竟上,你不妨忽视这个题目,clr会保护在两个异步伐用都中断后,你才不妨举行底下的操纵。至于它是如何实行的,你不妨不去管它。 究竟上,endinvoke利害常要害的。即使你运用了begininvoke,那你最佳运用endinvoke。由于你即使不运用endinvoke,那么后盾挪用的特殊就没有时机被捕获到。其余,运用了endinvoke不妨让clr开释异步伐用中所运用的资源,要不你的运用步调就大概展示资源揭发(resource leak)。 到这边,情景仍旧比拟领会了。运用delegate不妨让后盾线程包办当火线程去实行费时的操纵,进而使当火线程不被“遏制”,不妨赶快举行其它的处事。然而,即使当火线程经过endinvoke来获得异步伐用的截止,它又很大概被“遏制”。看上去有点“拆了东墙补西墙”的格式,犹如咱们没有获得什么长处。打个比如来说吧,你要到复印室去复印一批资料,这个处事要费时一个多钟点。同步伐用就表示着你本人亲身去复印,一个多小功夫再归来接待室作其它处事。异步伐用表示着你不妨把复印资料交到复印室,何处有专差控制复印。你放下资料后就不妨回到接待室去干其它处事了。但题目是,你要不停的察看资料能否复印好了,一旦创造复印结束后,就赶快取回作相映的操纵。你不停的察看(挪用代办的iscomplete本领)大概是“干等”(挪用代办的endinvoke本领)本质上仍旧把你“捆住”了,你没有能腾动手来干其它的事。能不许我把资料放到复印室就尽管了,等复印好后她们给我把资料送回顾?。谜底是不妨的,那即是运用回调因变量(callback function)。 还牢记咱们前方的谁人例子吗,咱们用代办挪用begininvoke的功夫,多了两个参数,个中一个即是回调因变量,其余一个是实行回调因变量的参数。回调因变量的道理是在后盾线实行完异步伐用的本领后,机动去实行的因变量(或本领)。在实行这个回调因变量的功夫,你还不妨指定参数。也是就说,你让复印室的复印员实行复印后,把资料给你放回到你的办公室桌上,而且每10页一摞。这个“放到办公室桌上”即是回调因变量,而“每10页一摞”即是回调因变量实行时运用的参数。 '回调因变量的参数dim myvalue as integer = 10'回调因变量的设置sub puttodesk(byval ar as iasyncresult)dim x as integer = cint(ar.asyncstate)'拿到参数'相映的操纵end sub'运用回调因变量的本领private callbackdelegate as asynccallback = addressof puttodesk...dim ar as system.iasyncresultar = delegate.begininvoke("class90",callbackdelegate, myvalue)在运用回调因变量时要提防,你的回调因变量必需和.net体例设置的asynccallback一道运用,即你的回调因变量必需和asynccallback具备一律的出面。也即是说它必需是子步调(sub procedure),必需有一个iasyncresult类东西为输出参数。 要提防的是回调因变量是由后盾线程来实行的(即是咱们所说的复印员)。这种实行本领在有些情景下会形成不小的题目。比方说,在windows的桌面运用中有如许一个准则,那即是十足用户界面元素的变动(表面以及属性)必需由那些界面元素的创造线程来举行(术语上叫界面干线程,primary ui thread)。即使其它线程试图革新界面元素,那么将会有不行猜测的成果。即使你违犯了这一规则,那么你的步调在表面上讲是不安定的,纵然是题目你偶尔还没有创造。 就上头一个例子而言,即使后盾线程从数据库里拿到了弟子名单,那么很大概它要实行的回调因变量即是革新界面上的一个下拉式列表(dropdown list),或是一个表格(grid)什么的。然而如许做又违犯了咱们所说的界面革新的线程规则。那么咱们该如何办呢? 本来这个题目并不难处置,安排师在安排.net的功夫仍旧商量到了这个题目。简直的处置方法我将鄙人

热门阅览

最新排行

Copyright © 2019-2021 大雀软件园(www.daque.cn) All Rights Reserved.