一区二区久久-一区二区三区www-一区二区三区久久-一区二区三区久久精品-麻豆国产一区二区在线观看-麻豆国产视频

ASP.NET2.0中數(shù)據(jù)源控件之異步數(shù)據(jù)訪問

  在第 1 部分和第 2 部分中,建立了 WeatherDataSource 控件,該控件針對 weather.com(英文)所提供的 XML API 來運(yùn)行,使用 WebRequest 和 WebResponse 來通過 HTTP 訪問數(shù)據(jù)。迄今為止,均是同步訪問該服務(wù)。因此,頁面處理被阻止,直到 Web 請求完成為止。此方法對于測試頁面是有效的,在小站點(diǎn)上也可能有效,但是在接收大量通信流量的站點(diǎn)上則會(huì)慘敗;例如門戶頁面,天氣模塊在其中可能非常常見。

  引言

  在線程池中有固定不變的大量線程可用于服務(wù)請求,遺憾的是,該解決方案并非僅僅提高限制(還會(huì)增加線程占用資源以及 CPU 占用資源)。因此,當(dāng)一個(gè)頁面被阻止而等候另一個(gè)服務(wù)器時(shí),它還在占用線程,因而可能會(huì)導(dǎo)致其他傳入的請求在隊(duì)列中等候更長的時(shí)間。這將導(dǎo)致對站點(diǎn)的訪問變慢,并降低 CPU 的利用率。在 Visual Studio 2005 中,我們引入了異步頁面,這使得控件能夠定義它們希望異步完成的任務(wù),即,無需阻止用來處理請求的線程。在此將不介紹異步頁面本身的詳細(xì)信息,Dmitry(英文)和 Fritz Onion(英文)中以前已經(jīng)有所介紹。此處要介紹的是如何在數(shù)據(jù)源控件中利用此功能,使用加載項(xiàng)框架來實(shí)現(xiàn)異步數(shù)據(jù)源。

  背景

  在第 1 部分中,間接提到了 DataSourceView 類的有些古怪的設(shè)計(jì):

public abstract class DataSourceView {
 public virtual void Select(DataSourceSelectArguments arguments,
  DataSourceViewSelectCallback callback);
 protected abstract IEnumerable ExecuteSelect(
  DataSourceSelectArguments arguments);
 ...
}

  您會(huì)注意到,公共 Select 方法實(shí)際上并不返回任何數(shù)據(jù)。而是接受一個(gè)回?fù)埽⑼ㄟ^該回?fù)軄矸祷財(cái)?shù)據(jù)。它只調(diào)用受保護(hù)的 ExecuteSelect(它始終執(zhí)行同步數(shù)據(jù)訪問)來檢索要退還給數(shù)據(jù)綁定控件的數(shù)據(jù)。DataSourceView 類的默認(rèn)實(shí)現(xiàn)實(shí)際上不會(huì)異步執(zhí)行任何操作。原因在于,并不存在任何現(xiàn)成的異步數(shù)據(jù)源控件。但 OM 的設(shè)計(jì)確實(shí)允許實(shí)現(xiàn)異步數(shù)據(jù)訪問,在這種設(shè)計(jì)下,數(shù)據(jù)在異步工作完成之后才可用。因此,我們就有了一個(gè)基于回?fù)艿哪P汀?br>
  那些熟悉框架中的異步 API 的人會(huì)注意到缺少了異步模式:公共 Select、BeginSelect 和 EndSelect 方法,在這些方法中,數(shù)據(jù)綁定控件選擇要調(diào)用哪些方法。但是,數(shù)據(jù)綁定控件并不能確定是選擇同步 API 還是選擇異步 API。此外,在數(shù)據(jù)綁定控件上添加屬性也毫無作用。數(shù)據(jù)源控件封裝了有關(guān)如何訪問數(shù)據(jù)存儲(chǔ)的詳細(xì)信息,對數(shù)據(jù)存儲(chǔ)的訪問是同步發(fā)生還是異步發(fā)生應(yīng)該根據(jù)數(shù)據(jù)源是否基于語義來決定或者根據(jù)自定義屬性來決定。潛在的“bool PerformAsyncDataAccess”屬性的正確位置適合于數(shù)據(jù)源控件本身。這還使得數(shù)據(jù)源控件可以使用一種方法來執(zhí)行數(shù)據(jù)訪問,即使多個(gè)數(shù)據(jù)綁定控件被綁定到同一個(gè)數(shù)據(jù)源。至此已多次解釋了該體系結(jié)構(gòu)所蘊(yùn)涵的這些微妙的概念,但愿能闡明該設(shè)計(jì)。

  關(guān)于異步任務(wù),最后要注意的一點(diǎn)是:頁面是否應(yīng)該執(zhí)行任何異步工作完全由頁面開發(fā)人員最終決定(通過 Page 指令的 Async 屬性)。因此,任何編寫良好的數(shù)據(jù)源控件必須退化為根據(jù)需要來執(zhí)行同步數(shù)據(jù)訪問。

  框架

  在此框架中(在此系列結(jié)尾會(huì)用示例的剩余部分來演示這一點(diǎn)),已將 AsyncDataSource 和 AsyncDataSourceView 基類放在一起,這些基類可以用于實(shí)現(xiàn)能夠執(zhí)行異步數(shù)據(jù)訪問的數(shù)據(jù)源控件。以下大概介紹了框架內(nèi)容,以及有助于弄清楚其含義的一些注釋:

public abstract class AsyncDataSourceControl : DataSourceControl,
IAsyncDataSource {
private bool _performAsyncDataAccess;

protected AsyncDataSourceControl() {
 _performAsyncDataAccess = true;
}

public virtual bool PerformAsyncDataAccess {
 get; set;
}

bool IAsyncDataSource.IsAsync {
 get { return _performAsyncDataAccess && Page.IsAsync; }
}
}

public abstract class AsyncDataSourceView : DataSourceView {

 protected abstract IAsyncResult BeginExecuteSelect(
  DataSourceSelectArguments arguments,
  AsyncCallback asyncCallback,
  object asyncState);

 protected abstract IEnumerable EndExecuteSelect(
  IAsyncResult asyncResult);

  protected override IEnumerable ExecuteSelect(
   DataSourceSelectArguments arguments) {
    //實(shí)現(xiàn)從 DataSourceView 中繼承的
    //抽象 ExecuteSelect 方法,
    //方法是使用 BeginExecuteSelect 和 EndExecuteSelect,
    //以便通過阻止來
    //進(jìn)行同步數(shù)據(jù)訪問。
   }

   private IAsyncResult OnBeginSelect(object sender,
     EventArgs e, AsyncCallback asyncCallback,
     object extraData);
   private void OnEndSelect(IAsyncResult asyncResult);

   public override void Select(DataSourceSelectArguments arguments,
    DataSourceViewSelectCallback callback) {
     if (_owner.IsAsync) {
      //使用 OnBeginSelect 和 OnEndSelect
      //作為 BeginEventHandler 和 EndEventHandler 方法,
      //來調(diào)用 Page.RegisterAsyncTask,
      //以指明需要
      //進(jìn)行異步工作。這些方法將依次
      //調(diào)用特定的
      //數(shù)據(jù)源實(shí)現(xiàn),方法是調(diào)用
      //已在此類中引入的
      //抽象 BeginExecuteSelect 和 EndExecuteSelect
      //方法。
     }
     else {
      //執(zhí)行同步數(shù)據(jù)訪問
      base.Select(arguments, callback);
     }
    }
   ...
}

  示例

  現(xiàn)在,新的 AsyncWeatherDataSource 將從 AsyncDataSourceControl 中派生,而 AsyncWeatherDataSourceView 將從 AsyncDataSourceView 中派生。

public class AsyncWeatherDataSource : AsyncDataSourceControl {

//與 WeatherDataSource 相同
}

private sealed class AsyncWeatherDataSourceView : AsyncDataSourceView {
private AsyncWeatherDataSource _owner;
private WeatherService _weatherService;

public AsyncWeatherDataSourceView(AsyncWeatherDataSource owner,
string viewName)
: base(owner, viewName) {
_owner = owner;
}

protected override IAsyncResult BeginExecuteSelect(DataSourceSelectArguments arguments,
AsyncCallback asyncCallback,
object asyncState) {
arguments.RaiseUnsupportedCapabilitiesError(this);

string zipCode = _owner.GetSelectedZipCode();
if (zipCode.Length == 0) {
return new SynchronousAsyncSelectResult(/* selectResult */
null,
asyncCallback, asyncState);
}

_weatherService = new WeatherService(zipCode);
return _weatherService.BeginGetWeather(asyncCallback, asyncState);
}

protected override IEnumerable EndExecuteSelect(IAsyncResult asyncResult) {
SynchronousAsyncSelectResult syncResult =
asyncResult as SynchronousAsyncSelectResult;
if (syncResult != null) {
return syncResult.SelectResult;
}
else {
Weather weatherObject =
_weatherService.EndGetWeather(asyncResult);
_weatherService = null;

if (weatherObject != null) {
return new Weather[] { weatherObject };
}
}

return null;
}
}

  要注意的關(guān)鍵問題是,在使用該框架時(shí),只需要實(shí)現(xiàn) BeginExecuteSelect 和 EndExecuteSelect。在它們的實(shí)現(xiàn)過程中,通常要調(diào)用由該框架中的各種對象(例如 WebRequest 或 IO 流)所揭示的 BeginXXX 和 EndXXX 方法(在 Visual Studio 2005 中,還需要調(diào)用 SqlDataCommand),并返回 IAsyncResult。在此示例中,有一個(gè)封裝了基礎(chǔ) WebRequest 對象的 WeatherService 幫助程序類。

  對于那些實(shí)際缺少異步模式的框架,您在此會(huì)看到有效的異步模式;以及您要實(shí)現(xiàn)的 BeginExecuteSelect 和 EndExecuteSelect,和您要調(diào)用以返回 IAsyncResult 實(shí)例的 Begin 和 End 方法。

  最有趣的可能是 SynchronousAsyncSelectResult 類(在某種程度上而言是一種矛盾)。此類是框架附帶的。它基本上是一個(gè) IAsyncResult 實(shí)現(xiàn),可使數(shù)據(jù)立即可用,并從其 IAsyncResult.CompletedSynchronously 屬性報(bào)告 true。到目前為止,這僅適用于未選擇郵政編碼的情況,并且需要返回 null(啟動(dòng)異步任務(wù)而只返回 null 是沒有意義的),但正如您會(huì)在下文中看到的,這在其他方案中也是有用的。

  頁面基礎(chǔ)結(jié)構(gòu)隱藏了在 Microsoft ASP.NET 上下文中執(zhí)行異步工作的大部分詳細(xì)信息。希望在此提供的框架使您執(zhí)行最少的操作就能編寫使用此基礎(chǔ)結(jié)構(gòu)的數(shù)據(jù)源。不過,就其本質(zhì)而言,實(shí)現(xiàn)異步行為是復(fù)雜的。有時(shí)候,第一次閱讀本文時(shí)會(huì)有一些疑問,而第二次閱讀時(shí)可能就明白了。您可以使用下面“我的評論”表單來發(fā)送問題或進(jìn)行討論。

AspNet技術(shù)ASP.NET2.0中數(shù)據(jù)源控件之異步數(shù)據(jù)訪問,轉(zhuǎn)載需保留來源!

鄭重聲明:本文版權(quán)歸原作者所有,轉(zhuǎn)載文章僅為傳播更多信息之目的,如作者信息標(biāo)記有誤,請第一時(shí)間聯(lián)系我們修改或刪除,多謝。

主站蜘蛛池模板: 国产成人一区二区三区影院免费 | 国产岛国 | 一区二区三区免费视频 www | 久久精品国产国语对白 | 婷婷亚洲视频 | 国产精品九九视频 | 亚洲另类小说网 | 亚洲国产天堂久久综合图区 | sifangtv| 亚洲精品在线不卡 | 亚洲色四在线视频观看 | 人人视频在线观看 | 色久悠悠色久在线观看 | 婷婷激情四月 | 中文字幕成人免费视频 | 女人被狂躁的免费视频网站软件 | 日本高清中文字幕一区二区三区a | 国产精选在线观看 | 国产亚洲欧美另类专区 | 一级毛片成人免费看免费不卡 | 香蕉免费一区二区三区在线观看 | 国产夫妻精品 | 一区二区中文字幕在线观看 | 成年人天堂 | 国产精品1区2区3区在线播放 | 国产视频网 | 岛国不卡 | 久久悠悠 | 欧洲一卡2卡三卡4卡免费观看 | 五月天天堂网 | 韩国一级片免费 | 四虎永久在线精品视频免费观看 | 国产精品视屏 | 四虎永久在线免费观看 | 在线视频精品免费 | 美女免费黄色 | 欧美高清狂热视频60一70 | 涩涩综合 | 在线视频观看国产 | 欧美亚洲高清日韩成人 | 亚综合|