c#

位置:IT落伍者 >> c# >> 浏览文章

.NET Framework中使用XML Web Service


发布日期:2023年10月04日
 
.NET Framework中使用XML Web Service

Microsoft?NET Framework 精简版的一个主要功能是能够使用 XML Web ServiceMicrosoft NET Framework 精简版支持以两种不同的方式使用 XML Web Service:同步和异步这两种方式各有优缺点同步 XML Web Service 调用编码简单而异步调用的编码略微复杂如果 XML Web Service 长时间无响应同步调用将冻结应用程序而异步调用则允许用户在调用 XML Web Service 期间与应用程序进行交互

通过 Smart Device(智能设备)项目使用 XML Web Service 时将发生几秒钟的初始延迟如果生成异步调用则此延迟不会冻结应用程序的用户界面NET Framework 精简版运行时设置 XML Web Service 的连接细节并缓存连接细节时将发生此延迟通常情况下这会导致应用程序无响应以后再调用 XML Web Service 时性能将会显着提高

本文说明了如何向 Smart Device(智能设备)项目添加对 XML Web Service 的 Web 引用以及如何同步和异步调用 XML Web Service

本文假设您在使用 Microsoft Visual Studio? NET 创建智能设备应用程序方面有一定的经验

使用 Web 服务

要在 Smart Device(智能设备)项目中使用 XML Web Service您需要在项目中添加 Web 引用项目通过 Web 引用来使用 XML Web Service在项目中添加 Web 引用时Visual Studio NET 将自动生成一个代理类(其中包含用作 XML Web Service 每个公开方法的代理的方法)默认情况下代理类不会显示在 Solution Explorer(解决方案资源管理器)中应用程序使用自动生成的类(而不是使用自己的代码修改的类)来访问 XML Web Service

要向项目中添加 Web 引用请执行以下操作

在 Solution Explorer(解决方案资源管理器)中选择要使用 XML Web Service 的项目 在 Project(项目)菜单上选择 Add Web Reference(添加 Web 引用) 输入要使用的 XML Web Service 的 URL并单击 Go(转到)按钮

Add Web Reference(添加 Web 引用)对话框

在 Web reference name(Web 引用名称)字段中输入将在代码中用于以编程方式访问选定 XML Web Service 的名称 单击 Add Reference(添加引用)按钮以在应用程序中创建对 XML Web Service 的引用新引用将显示在 Solution Explorer(解决方案资源管理器)中选定项目的 Web References(Web 引用)节点下

Visual Studio NET 在添加 Web 引用时生成的代理类还包含用于同步或异步访问 Web 服务的方法现在我们来看一下如何实现此目的

生成同步 XML Web Service 调用

生成对 XML Web Service 的同步调用时调用线程将中断直到 XML Web Service 返回方法调用的结果如果在服务器中调用的方法不需要太多的处理时间且将迅速返回则同步调用比较有用此外同步 XML Web Service 调用比异步调用容易实现但是通过 NET Framework 精简版应用程序调用 XML Web Service 时将发生重大延迟这将使应用程序锁定并使用户接口冻结直到返回方法调用为止

要生成同步 XML Web Service 调用需要创建一个代理类实例然后调用此代理类中的方法方式与调用其他类中的方法相同以下代码示例演示了如何生成对 XML Web Service 的 Web 方法(用于返回有关 SQL Server 附带的 Pubs 示例数据库中的书籍的信息)的调用然后代码将通过 DataSet 将数据加载到 Windows 窗体上的 ListView 控件

此示例假设您在添加 Web 引用(如本文第一部分所述)时将 Web 引用命名为 BookCatalogBookCatalog XML Web Service 包含 GetItems Web 方法该方法将返回一个 DataSet 对象此代码取自本文附带的下载中的 button_Click() 事件处理程序

// 调用 XML Web Service // 创建 Web 服务代理类的实例BookCatalogService bookcatalog = new BookCatalogService()

// 创建 DataSet 对象的新实例并调用 Web 服务// 方法 GetItems 检索书籍列表DataSet ds = bookcatalogGetItems()

// // 处理 DataSet // 遍历 DataSet 并将每个行的 Title_ID 和 Title 字段

// 添加至 ListViewforeach(DataRow drBook in dsTables[]Rows) {

// 创建一个新 ListViewItem 添加到 ListView ListViewItem book = new ListViewItem()

// 将 Title_ID 字段指定给 Text 属性 bookText = drBook[Title_ID]ToString()

// 将 Title 字段指定给第一个 SubItem bookSubItem[]Text = drBook[Title]ToString() // 将书 ListViewItem 添加到 ListView listViewItemsAdd(book)

}//

生成异步 Web 服务调用

通过生成异步 XML Web Service 调用您可以在等待 XML Web Service 作出响应时继续使用调用线程也就是说用户可以在应用程序未锁定的情况下继续与其交互而 XML Web Service 访问也将继续进行这是一种更好的设计模式通过使用多线程支持可以更有效地在智能设备应用程序中使用线程生成异步调用时将在不同于运行用户界面的线程中生成调用XML Web Service 应用程序不需要任何特殊配置即可支持异步访问也不需要知道调用方式是同步还是异步代理类中的每个同步方法都有相应的 Begin 和 End 方法例如如果 XML Web Service 方法名为 GetItems则异步方法为 BeginGetItems 和 EndGetItems

异步调用 XML Web Service 分两个步骤第一步调用 Begin 方法以初始化 Web 方法调用第二步调用 End 方法以完成 XML Web Service 调用并检索 XML Web Service 的响应

Begin 方法返回一个 SystemWebServicesProtocolWebClientAsyncResult 对象用于实现 SystemIAsyncResult 接口此对象提供关于待定异步调用的状态信息通过将此对象传递给 End 方法代理类可以标识要完成的请求尤其是同时生成多个异步调用时

有多种方法可以确定异步 XML Web Service 调用何时完成

向 Begin 方法传递一个回调委托回调委托将在 XML Web Service 调用完成后执行 使用 IAsyncResultAsyncWaitHandle 对象的 WaitHandle 方法之一强制应用程序等待使用 WaitHandle 类的方法时客户端也可以指定超时超时过后客户端将不再等待调用的 XML Web Service 的结果 在主线程代码中轮询 IAsyncResultIsCompleted 属性的值以查找值 true如果此属性为 true则调用 End 方法以检索 XML Web Service 的响应 可直接调用 End 方法而无需使用其他技术确定异步 XML Web Service 调用是否完成此方法将中断调用线程的执行直到异步调用完成为止

最有效的方法是向 Begin 方法传递一个回调委托因为回调函数在等待响应期间不会中断线程XML Web Service 返回其响应时回调委托将在新线程中执行然后在回调中调用 End 方法

以下代码演示了如何创建异步 XML Web Service 调用此代码显示了对 BeginGetItems 的调用语法如下

BeginGetItems(SystemAsyncCallback callback object asyncState)

BeginGetItems 使用两个参数第一个是 AsyncCallback 对象它是通过在构造函数内传递 ServiceCallback 方法的地址创建的第二个参数是对象类型的参数可以传递任何可帮助您处理 XML Web Service 响应的对象可以通过获取回调方法中 IAsyncResult 参数的 AsyncState 属性来访问此同一对象在以下示例中以这种方式传递的对象是 XML Web Service 代理对象因此在执行回调委托时可以调用 EndGetItems如下面的 ServiceCallback 方法所示

private void button_Click(object sender SystemEventArgs e){

// 禁用 Async 按钮并清除任何数据的 ListView

// 创建 XML Web Service 代理类的实例 BookCatalogService ws = new BookCatalogService()

// 创建对回调委托的引用 AsyncCallback cb = new AsyncCallback(ServiceCallback)

// 调用 Begin 方法将回调委托和

// 此代理类实例作为 AsyncState 对象传递 wsBeginGetItems(cbws)}private void ServiceCallback(IAsyncResult ar){

// 将 AsyncState 对象转换为代理对象 BookCatalogService ws = (BookCatalogService)arAsyncState;

// 调用 End 方法并将响应指定给 DataSet DataSet ds = wsEndGetItems(ar)

// 遍历 DataSet 并将每个行的 Title_ID 和 Title 字段

// 添加至 ListView foreach(DataRow drBook in dsTables[]Rows) {

// 创建一个新 ListViewItem 添加到 ListView ListViewItem book = new ListViewItem()

// 将 Title_ID 字段指定给 Text 属性 bookText = drBook[Title_ID]ToString()

// 将 Title 字段指定给第一个 SubItem bookSubItem[]Text = drBook[Title]ToString()

// 将书 ListViewItem 添加到 ListView listViewItemsAdd(book)

}}

尽管生成异步 XML Web Service 调用比生成同步调用所需的代码稍多但最终结果可以生成响应更快的应用程序因此还是值得的

重要信息异步调用 XML Web Service 时请使用多线程编程技术

生成异步 XML Web Service 调用时如果不使用多线程技术则在两个或多个线程同时尝试访问同一数据时将会出现问题技术之一(如以下代码所示)就是在 C# 中使用 lock 语句来获取对对象的相互独占的访问权以拒绝其他线程的访问

private void ServiceCallback(IAsyncResult ar){ // 将 AsyncState 对象转换为代理对象 BookCatalogService ws = (BookCatalogService)arAsyncState; // 调用 End 方法并将响应指定给 DataSet DataSet ds = wsEndGetItems(ar) // 使用 lock 语句防止其他线程访问 // listview直到完成对它的更新 lock(thislistView) { // 遍历 DataSet 并将每个行的 Title_ID 以及 // Title 字段添加至 ListView foreach(DataRow drBook in dsTables[]Rows) { // 创建一个新 ListViewItem 添加到 ListView ListViewItem book = new ListViewItem() // 将 Title_ID 字段指定给 Text 属性 bookText = drBook[Title_ID]ToString() // 将 Title 字段指定给第一个 SubItem bookSubItem[]Text = drBook[Title]ToString() // 将书 ListViewItem 添加到 ListView listViewItemsAdd(book) } }}

您还应该学习其他技术例如使用 Monitor 类和 ControlInvoke 来生成线程安全的应用程序有关多线程编程技术的详细信息可在 MSDN? Library 中找到

               

上一篇:漫谈.Net PetShop和Duwamish ADO.NET数据库编程

下一篇:.NET中获取电脑名、IP及用户名方法