设计“可脱机”的 Microsoft .NET 框架压缩版应用程序

Christian Forsberg
businessanyplace.net

2003 年 8 月

适用于:

   Microsoft® Visual Studio® .NET 2003
    Microsoft .NET Framework 精简版
    Microsoft Windows® Powered Pocket PC

摘要:通过了解可选设计,学习“有时脱机”的应用程序如何与服务器同步。本文还包含使用 Web 服务实现应用程序同步的示例应用程序。(本文包含一些指向英文站点的链接。)

从 Microsoft Download Center 下载示例应用程序 Sometimes_offline.exe

目录

简介
同步策略
数据库同步
应用程序同步
Reading Anyplace 示例
代码示例
小结

简介

越来越多的 Microsoft® Windows® Powered Pocket PC 连接在一起,为分布式应用程序带来了很多新的机会。尽管许多 Web 应用程序可以在这些设备上运行,但是还是常常需要脱机操作支持。为保持信息在集成环境下的一致性,脱机应用程序需要与 Office 背后的支持系统保持数据同步。我们先来了解一些有关体系结构的基础知识。

在现代应用程序设计中,采用多层模式通常是一个规则,而不是一种特殊情况。在服务器上,我们已经习惯于将用户服务(通常是演示)、商业服务和数据服务相分离。使用 Microsoft Visual Studio .NET 2003 这样支持移动设备开发的工具,也可以对移动应用程序采用同样的模式。在“有时脱机”的应用程序中,运行在设备上的应用程序即使没有连接服务器也能正常工作。这种应用程序应该具有一个多层设计,以获得服务器端应用程序那样的优点(基于组件、可重复使用性、可维护性等等)。图 1 概括显示了可能的分布式设计。

 

图 1:设备和服务器中的应用程序层

移动应用程序使用类似于 Mobile Web Development with ASP.NET 的技术在服务器上完全实现。然后,客户端只需使用内置的浏览器访问该应用程序。如果需要支持脱机功能,应用程序必须在设备上运行。与此相关的技术包括 Smart Device ProgrammabilityMicrosoft .NET Framework 精简版

同步策略

分布式应用程序通常需要连接到服务器才能获得任务关键的信息,但目前尚无法实现“始终连接”设备这一梦想,所以更需要支持脱机操作。因此,数据需要在本地设备上进行维护,然后与服务器同步。要使脱机设备数据与服务器同步,最重要的选项是数据库同步和应用程序同步。图 2 从概念上概要显示了这两个选项。

图 2:数据库同步与应用程序同步

数据库同步是保持设备数据与服务器数据同时更新的一种非常有效的方法。只有必要的信息才被传输,即使是在压缩传输中。但是,如果同步中涉及到逻辑,则最好通过编程方式解决此问题。所谓的“应用程序同步”,表示进行同步操作时,设备上的商业逻辑层将与服务器上的商业逻辑层相连接。在许多实际的应用程序中,能够结合这两个选项才称得上是最好的设计。

数据库同步

如果在 SQL Server™ for Windows CE (SQLCE) 数据库中维护设备数据,则 .NET Framework 精简版需要提供支持功能,以同步设备数据与 SQL Server 数据库数据。此功能在 System.Data.SqlServerCe 命名空间的 SqlCeReplication 类中实现。实现方法有两种:远程数据访问(Remote Data Access,RDA)与合并复制 (Merge Replication)。RDA 方法是将表数据拖出/拖入设备的简便方法,而合并复制用于更高级的同步。有关详细信息,请参阅“SQL Server 2000 Windows CE Edition and the .NET Framework 精简版”一文,有关合并复制的详细信息,请参阅“Programming Merge Replication with the Microsoft .NET Framework 精简版”一文。

如果数据同步中未涉及太多逻辑,则采用数据库同步。这是一个快速有效的方法,尤其是在需要传输加载数据时。它需要将设备数据存储在 SQLCE 数据库中。

正如图 2 中的虚线所示,如果只涉及到客户端同步逻辑,也可以使用 System.Data.SqlClient 命名空间访问服务器数据库。

应用程序同步

在许多情况下,数据同步涉及的逻辑所需要的机制要超过数据库同步所允许的复杂程度。应用程序同步非常类似于应用程序集成,即两个应用程序连接起来以交换数据。.NET Framework 精简版中实现此操作的最明显的结构是使用 XML Web Service。使用 Web 服务,设备可以以松散耦合的方式并基于 XML 和 HTTP 之类的标准连接到服务器端逻辑。.NET Framework 精简版中的 Web 服务支持可以在 System.Web.Services 命名空间中找到。

对于更高级的同步方案,应用程序同步是一种很好的方法。让我们看一下示例实现。

Reading Anyplace 示例

Reading Anyplace 示例应用程序显示了检查员如何脱机记录米读数然后将该读数与服务器同步。应用程序由一个表格组成,如图 3 所示。

图 3:Reading Anyplace 示例

可以输入 Meter ID 和位置,当按下 Record(记录)按钮时,记录将添加到列表中。每个新记录都带有“New”标记。如果再次使用同一个 Meter ID,相应的记录将被更新。按下 Synchronize(同步)按钮时,将使用 Web 服务将所有记录发送到服务器。然后,服务器响应被更新到列表中的“Remark”列中。正确的记录被标记为“OK”,不正确的记录将被标上说明存在验证错误的标记(例如图 3 中,ID 为 1234 的米值被标记为“Too high!”)。按下 Clean up(清除)按钮将清除所有标记为“OK”的记录。

该示例中的逻辑是,在设备数据与服务器同步之前不能进行米读数验证。由于应用程序同步设计,这种情况是可能的,而数据库同步就更难实现。

代码示例

由于本示例的重点并不是要显示完整的服务器实现,因此服务器端 Web 服务实现简单表示如下:

[WebMethod]
public string SyncReading(string ID, int Position)
{
  if (ID == "1234" && Position > 1000)
    return "Too high!";
  else
    return "OK";
}
      

对示例 Web 服务进行了硬编码,只检查 ID 为 1234,值大于 1000 的米位置。在实际的方案中,可能会与从服务器数据库中存储的上一个读数导出的预测位置进行比较。此外,如果将其他检查员以前的读数提供给客户端,该示例需要在服务器端加入更多同步逻辑。

在客户端,为 Web 服务创建 Web 引用时,Synchronization(同步)按钮的代码应如下所示:

Cursor.Current = Cursors.WaitCursor;

Reading.Server.Sync sync = new Reading.Server.Sync();

try
{
  foreach (ListViewItem lvi in lvwItems.Items)
    if (lvi.SubItems[2].Text == "New")
      lvi.SubItems[2].Text = sync.SyncReading(lvi.Text,
        Convert.ToInt32(lvi.SubItems[1].Text));
}
catch (Exception ex)
{
  MessageBox.Show("Could not call Web Service!", this.Text);
}
finally
{
  Cursor.Current = Cursors.Default;
}
      

显示等待光标时,将创建 Web 服务对象 (sync)。然后,ListView 中的每个新记录(标记为“New”)将被发送到 Web 服务方法 (SyncReading),ListView 中的“Remarks”列将使用 Web 服务响应进行更新。如果出现错误,则显示消息框。无论发生什么,光标都会还原。

在此示例中,本地数据仅在 ListView 控件中维护,当示例应用程序结束时,这些数据将丢失。在实际的方案中,数据可能会传送到 DataSet 中并存储为 XML 文件或传输到 SQLCE 数据库中。

小结

在“有时脱机”的应用程序中,如果需要类似服务器端验证的逻辑,最好采用应用程序同步的方法实现同步。Web 服务是实施应用程序同步的一种好方法,因为它允许客户端逻辑连接到服务器端逻辑。因此,支持从基于 .NET Framework 精简版的本地 Pocket PC 应用程序中调用 Web 服务确实很重要。

原文地址:https://www.cnblogs.com/youyou/p/176880.html