Silverlight 异步域操作详解
在Silverlight 3的异步域操作可谓家常便饭。因此,全面地理解异步域操作相关知识是基于RIA服务技术开发Silverlight应用的必修课。在本文中,我们将以精简的形式剖析RIA服务编程中异步域操作中涉及的要点并归纳应注意的问题。
1.Silverlight 3异步域操作
DomainContext支持3种类型域操作:Query,Submit和Invoke。这些操作中的的每一种都有一个相应的操作类型用于描述正在进行中的异步操作。例如,当一个查询加载到一个DomainContext中,异步的Load调用将立即返回一个LoadOperation实例。请参考如下代码:
HRContext _ctxt = new HRContext(); var query = from e in _ctxt.GetEmployeesQuery() where e.ManagerID == 1 select e; LoadOperation lo = _ctxt.Load(query);
上面的操作结果既提供了有关于正在进行的操作的动态的可绑定的状态信息,也提供了可取消当前操作的支持。同样地,一个提交请求将返回一个SubmitOperation,而服务操作调用将返回一个InvokeOperation。
接下来,我们将详细地讨论这些Silverlight 3异步域操作及其基类有关知识。
2.基类OperationBase
这个类是所有.NET RIA服务异步操作的基类。这个类实现了接口INotifyPropertyChanged,因此,它的操作状态成员可以是数据绑定型的,而且当操作的完成状态改变时,将会引发通知。
基类OperationBase提供了如下成员:
◆IsComplete—一旦操作完成便返回true。注意,当一项操作成功结束,或者是完成但仍带有错误,或者是此操作被取消,都被认为是操作完成。
◆Completed事件—当一项操作完成时引发此事件。
◆UserState—与操作相关的用户状态。
◆Cancel()/CanCancel/IsCanceled—如果操作能够被取消并且没有完成,那么CanCancel将返回true。在取消操作前,将会检查CanCancel的值。如果操作已经完成,则将抛出一个异常。
◆Error/HasError—如果操作已经完成,但发生了错误,那么HasError的值将为true,而且Error中将包含相应的异常信息。
下面你将会看到,一个域操作中还可以指定一个操作完成对应的回调函数。如果指定了一个回调函数,那么,此回调函数在任何情况下也会被调用,无论此操作是成功结束,还是完成但仍带有错误,还是此操作被取消。
另外值得注意的是,这个回调函数在Completed事件引发以前也会被调用。
3.LoadOperation操作
DomainContext.Load将返回一个LoadOperation的实例。LoadOperation描述了一个正在操作中的异步加载操作。另外,此操作还提供了下面额外的状态及功能支持:
◆Entities—一个已加载的实体的强类型枚举类型。一旦调用返回,集合即变为空。注意,此集合实现了接口INotifyCollectionChanged,当操作完成时自新将得到更新。
◆AllEntities—由查询操作加载的所有实体的集合,而且还包括任何相关联的实体。注意,此对象也实现了接口INotifyCollectionChanged。一旦调用返回,集合即变为空。注意,此对象也实现了接口INotifyCollectionChanged,当操作完成时自新将得到更新。
◆TotalEntityCount—返回查询中对应的所有服务器端实体总数。
◆EntityQuery—用于初始化加载操作。
◆MergeOption—加载操作中指定的MergeOption。
下面的代码展示了如何指定一个加载回调函数:
object state =……//用户状态 LoadOperation lo = _ctxt.Load(query, EmployeesLoadedCallback, state); …… private void EmployeesLoadedCallback(LoadOperation lo) { if (!lo.HasError) { object state = lo.UserState; foreach (Employee employee in lo.Entities) { //处理已加载的实例 } } else { //处理错误 } } 要指定一个完成事件处理器,可以像下面这样使用LoadOperation.Completed。 object state =……//用户状态 LoadOperation lo = _ctxt.Load(query, null, state); lo.Completed += this.OnEmployeesLoaded; …… private void OnEmployeesLoaded(object sender, EventArgs e) { LoadOperation lo = (LoadOperation)sender; …… }
当有许多方面(可能是外面的)对当前操作进度感兴趣时,那么上面的事件处理器创建是非常有用的。
4.SubmitOperation操作
DomainContext.SubmitChanges方法将返回一个SubmitOperation的实例。其中,SubmitOperation代表了正在进行的异步提交操作;此外,DomainContext.SubmitChanges方法还提供了下面额外的状态及功能支持:
◆ChangeSet—正在提交的EntityChangeSet
◆EntitiesInError—对于一个产生校验或冲突错误的提交操作来说,它代表了产生错误的实体的集合。
另外,回调函数及Completed事件的提交与前面解释的LoadOperation中的使用方式一致,在此不再赘述。
六、InvokeOperation操作
当调用一个ServiceOperation(服务操作)时,将返回一个强类型的InvokeOperation。这里,T是ServiceOperation操作的返回类型。归纳来看,InvokeOperation操作提供了下面额外的状态及功能支持:
◆OperationName—要调用的操作的名字
◆Parameters—要操作的名字/值形式的字典参数
◆ValidationErrors—当调用失败时对应的检验错误信息的集合
◆Value—ServiceOperation返回的值
另外,回调函数及Completed事件的提交与前面解释的LoadOperation中的使用方式一致,在此不再赘述。
5.小结
本文简要地总结了RIA服务开发中Silverlight 3异步域操作支持的3种类型的重要的域操作:Query,Submit和Invoke。其中的每一种操作都有一个相应的操作类型用于描述正在进行中的异步操作。我们对这些RIA服务操作使用参数、注意事项及使用场景等进行了归纳,并给出片断代码例证。