注册通行证 用户名 密码
  • 文章投稿
  • 博客
  • 论坛
  • 设为首页
  • 加入收藏
jztop.com网络技术
  • 首页
  • | iT新闻
  • | 操作系统
  • | 组网建网
  • | 网络安全
  • | 程序开发
  • | 办公一族
  • | 工具软件
  • | 网页制作
  • | 多媒体制作
  • | 网吧技术
  • | 服务器
  • | 专题教程
Vista | 软件评测 | 系统备份 | 优化 | 进程 | 聊天 | 病毒 | Linux | 黑客 | 防火墙 | 数据库 | Web开发 | Java | Word | 游戏 | 32位开发 | 移动开发
当前位置:首页 > 程序开发 > 微软开发专栏 > ASP.NET > 内容正文

ASP.NET2.0中数据源控件之异步数据访问

发布时间:2006-02-17 16:24:51 来源:msdn 网友评论 0 条
  在第 1 部分和第 2 部分中,建立了 WeatherDataSource 控件,该控件针对 weather.com(英文)所提供的 XML API 来运行,使用 WebRequest 和 WebResponse 来通过 HTTP 访问数据。迄今为止,均是同步访问该服务。因此,页面处理被阻止,直到 Web 请求完成为止。此方法对于测试页面是有效的,在小站点上也可能有效,但是在接收大量通信流量的站点上则会惨败;例如门户页面,天气模块在其中可能非常常见。

  引言

  在线程池中有固定不变的大量线程可用于服务请求,遗憾的是,该解决方案并非仅仅提高限制(还会增加线程占用资源以及 CPU 占用资源)。因此,当一个页面被阻止而等候另一个服务器时,它还在占用线程,因而可能会导致其他传入的请求在队列中等候更长的时间。这将导致对站点的访问变慢,并降低 CPU 的利用率。在 Visual Studio 2005 中,我们引入了异步页面,这使得控件能够定义它们希望异步完成的任务,即,无需阻止用来处理请求的线程。在此将不介绍异步页面本身的详细信息,Dmitry(英文)和 Fritz Onion(英文)中以前已经有所介绍。此处要介绍的是如何在数据源控件中利用此功能,使用加载项框架来实现异步数据源。

  背景

  在第 1 部分中,间接提到了 DataSourceView 类的有些古怪的设计:

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

  您会注意到,公共 Select 方法实际上并不返回任何数据。而是接受一个回拨,并通过该回拨来返回数据。它只调用受保护的 ExecuteSelect(它始终执行同步数据访问)来检索要退还给数据绑定控件的数据。DataSourceView 类的默认实现实际上不会异步执行任何操作。原因在于,并不存在任何现成的异步数据源控件。但 OM 的设计确实允许实现异步数据访问,在这种设计下,数据在异步工作完成之后才可用。因此,我们就有了一个基于回拨的模型。

  那些熟悉框架中的异步 API 的人会注意到缺少了异步模式:公共 Select、BeginSelect 和 EndSelect 方法,在这些方法中,数据绑定控件选择要调用哪些方法。但是,数据绑定控件并不能确定是选择同步 API 还是选择异步 API。此外,在数据绑定控件上添加属性也毫无作用。数据源控件封装了有关如何访问数据存储的详细信息,对数据存储的访问是同步发生还是异步发生应该根据数据源是否基于语义来决定或者根据自定义属性来决定。潜在的“bool PerformAsyncDataAccess”属性的正确位置适合于数据源控件本身。这还使得数据源控件可以使用一种方法来执行数据访问,即使多个数据绑定控件被绑定到同一个数据源。至此已多次解释了该体系结构所蕴涵的这些微妙的概念,但愿能阐明该设计。

  关于异步任务,最后要注意的一点是:页面是否应该执行任何异步工作完全由页面开发人员最终决定(通过 Page 指令的 Async 属性)。因此,任何编写良好的数据源控件必须退化为根据需要来执行同步数据访问。

  框架

  在此框架中(在此系列结尾会用示例的剩余部分来演示这一点),已将 AsyncDataSource 和 AsyncDataSourceView 基类放在一起,这些基类可以用于实现能够执行异步数据访问的数据源控件。以下大概介绍了框架内容,以及有助于弄清楚其含义的一些注释:

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) {
    //实现从 DataSourceView 中继承的
    //抽象 ExecuteSelect 方法,
    //方法是使用 BeginExecuteSelect 和 EndExecuteSelect,
    //以便通过阻止来
    //进行同步数据访问。
   }

   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 方法,
      //来调用 Page.RegisterAsyncTask,
      //以指明需要
      //进行异步工作。这些方法将依次
      //调用特定的
      //数据源实现,方法是调用
      //已在此类中引入的
      //抽象 BeginExecuteSelect 和 EndExecuteSelect
      //方法。
     }
     else {
      //执行同步数据访问
      base.Select(arguments, callback);
     }
    }
   ...
}

  示例

  现在,新的 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;
}
}

  要注意的关键问题是,在使用该框架时,只需要实现 BeginExecuteSelect 和 EndExecuteSelect。在它们的实现过程中,通常要调用由该框架中的各种对象(例如 WebRequest 或 IO 流)所揭示的 BeginXXX 和 EndXXX 方法(在 Visual Studio 2005 中,还需要调用 SqlDataCommand),并返回 IAsyncResult。在此示例中,有一个封装了基础 WebRequest 对象的 WeatherService 帮助程序类。

  对于那些实际缺少异步模式的框架,您在此会看到有效的异步模式;以及您要实现的 BeginExecuteSelect 和 EndExecuteSelect,和您要调用以返回 IAsyncResult 实例的 Begin 和 End 方法。

  最有趣的可能是 SynchronousAsyncSelectResult 类(在某种程度上而言是一种矛盾)。此类是框架附带的。它基本上是一个 IAsyncResult 实现,可使数据立即可用,并从其 IAsyncResult.CompletedSynchronously 属性报告 true。到目前为止,这仅适用于未选择邮政编码的情况,并且需要返回 null(启动异步任务而只返回 null 是没有意义的),但正如您会在下文中看到的,这在其他方案中也是有用的。

  页面基础结构隐藏了在 Microsoft ASP.NET 上下文中执行异步工作的大部分详细信息。希望在此提供的框架使您执行最少的操作就能编写使用此基础结构的数据源。不过,就其本质而言,实现异步行为是复杂的。有时候,第一次阅读本文时会有一些疑问,而第二次阅读时可能就明白了。您可以使用下面“我的评论”表单来发送问题或进行讨论。
关于 ASP.NET2.0 数据源控件 的新闻
  • ASP.NET2.0中使用数据源控件之参数
  • ASP.NET2.0中使用数据源控件之基础知识
  • ASP.NET2.0实现无刷新客户端回调
  • 剖析ASP.NET2.0站点导航功能之建立导航
【评论】【收藏本文】【打印】【关闭】
上一篇文章:ASP.NET2.0中使用数据源控件之参数
下一篇文章:ASP.NET编程入门随想之宽容
讨论区
查看
已有 0 位对此新闻感兴趣的网友发表了看法
匿名发表
注册通行证 登陆
图文阅读推荐
全站资源
  • 微软官方入门教程19:轻松掌握Vista系统的快
  • 微软2008大冲击,预借Vista SP1力促Vista市
  • 在收件箱中获得 Windows Vista 的最新更新
  • 微软官方Vista入门教程全集19篇(Vista学院
  • Windows Vista 的成功将势不可挡
  • 快快抛弃Vista,拥抱XP SP3!你觉得呢?
  • 浅谈Vista系统关闭虚拟内存与使用内存盘加速
  • 嘿嘿,按下键盘上面的三个键,马上让你的Vi
  • Windows Vista的盗版率只有Windows XP的一半
  • 3DMark和PCMark Vantage新版将只支持Vista系
阅读排行
  • 用ASP.NET 2.0设计网络在线投票系统
  • 在ASP.Net 2.0中实现多语言界面的方法
  • 轻松加密ASP.NET 2.0 Web程序配置信息
  • 在ASP.NET中使用AJAX的简单方法
  • .NET 2.0中的企业库异常处理块简述
  • 面向.NET开发人员的Ajax 技术平台策略
  • 揭开ASP.NET中Cookie编程的奥秘
  • ASP.NET2.0服务器控件之创建自定义控件
  • ASP.NET2.0中Gridview中数据操作技巧
  • ASP.NET 2.0发送电子邮件全面剖析之二
最新技术文档
  • 在ASP.NET中使用AJAX的简单方法
  • 轻松加密ASP.NET 2.0 Web程序配置信息
  • 虚拟主机下asp.net 2.0的导航控件treeview,
  • asp.net身份验证和授权
  • 迁移你的Web页面到ASP.NET AJAX 1.0
  • ASP.NET技巧:HTTP性能调优之设置连接失效时
  • 如何改变asp.net项目名称
  • ASP.NET 2.0页面性能的考虑
  • ASP.NET 2.0打造购物车和支付系统之二
  • asp.net URL重写(URLRewriter) 之简化版
专题教程
  • 大话G游 专题:手机病毒揭密
  • ARP攻击防范与解决方案 路由故障处理手册
  • Picasa中文版_Picasa教程 专题:清除流氓软件
  • Firefox专题 seo搜索引擎优化专区
  • 重装Windows必知的事情 装机之必备软件大行动
病毒专杀栏
  • 杀毒软件反被病毒杀 连"救命"都不能喊
  • 金山ARP防火墙
  • 还原卡神话破灭“机器狗”病毒来势汹汹
  • cctv经济半小时:你的手机现在安全吗?
  • 新挂马方式开始流行 ARP挂马称雄局域网
  • 木马和病毒清除的通用解法
  • IP地址不再冲突 查找ARP攻击者元凶
  • 教你几招识别和防御Web网页木马
  • 分析:封杀BT只是暂时的止痛药
  • QQ爆危险漏洞,“QQ游戏邀请大盗”邀请你玩病
关于我们 | 诚聘英才 | 联系我们 | 版权声明 | 网站大事 | 网站地图 | 意见建议
CopyRight 2005-2007 Jztop.Com 版权所有 未经许可 请勿转载