ASP.NET 中的“即发即弃” Web 方法
本文档介绍在传统 ASP.NET Web 服务中创建和使用单向 Web 方法。
引言:
在很多情况下,我们可能会遇到这样的情况:我们想从正在使用的应用程序调用一个 Web 方法,但我们不想等待请求被处理,或者我们不期望从该 Web 方法中获得任何返回值。就像我们说的“即发即弃”。
例如:我们有一个客户端 Web 应用程序,它使用一个 Web 服务。这个特定的 Web 方法被 Web 应用程序用来将大量记录从某个文件推送到数据库。并且,正在使用的应用程序不期望得到任何结果,它只希望知道 Web 方法是否被成功调用。调用此方法后,Web 应用程序将继续进行自己的处理,而无需等待 Web 方法完成其处理。
如何实现此功能:
要实现上述功能,在 asp.net web service 中创建 Web 方法时,我们必须使用属性[SoapDocumentMethod(OneWay = true)]来修饰 Web 方法。您认为这能满足上述要求吗?它不能。要实现这一点,我们必须以一种能够适应单向异步机制的方式设置 Web 服务的代理类。我们该怎么做?下一节将通过示例进行说明。不仅要修改代理和 Web 方法,还要在正在使用的客户端中进行支持性的管道连接才能实现这一点。
示例项目: 在这里,我将通过一个示例项目,一步一步地展示这一点。1) 创建一个用 SoapDocumentMethod One-way 设置为 true 的 Web 服务,它接受一个 int 参数,并让线程等待几毫秒以显示一些正在发生的事情,否则您可以拥有自己的代码,这些代码需要一些时间来完成执行。 在这里,我们完成了 Web 方法的工作,除此之外,在此方面没有其他事情需要做。有一件重要的事情需要注意,那就是 Web 方法的返回类型在这里被设置为 void。
2) 在同一个解决方案中创建(为了方便,在同一个解决方案中)一个正在使用的应用程序。
好了,我们已经创建了一个 Web 服务和一个使用者。我们的下一个任务是为单向方法的使用进行管道连接,为此,我们需要在我们的 Web 应用程序的使用者中创建一个代理。
3) 通过添加 Web 引用创建代理的步骤如下:
我们已成功地在我们的 Web 应用程序的使用者中添加了 Web 引用。您可以在下面的截图看到。
到目前为止一切都很好,对吧?现在我们将在我们的 Web 应用程序的使用者中进行管道连接。看
为此,我将创建一个 Web 服务对象在我们正在使用的 Web 应用程序中。查看我们从 IntelliSense 获得的提示,它将显示 2 个 Web 方法,但我们只创建了一个,对吧?
看看下面显示所有 Web 方法的截图。

是的,您可以看到我们的 HelloWorldOneWay、HelloWorldOneWayAsync 和一个名为 HellowWorldOneWayCompleated 的事件。


我所做的是创建代理对象。然后我将 HellowWorldOnewayCompleated 事件与一个事件处理程序连接起来。您可以在下面的整个代码片段中看到。
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Diagnostics;
namespace OnewayConsumer
{
public partial class _Default : System.Web.UI.Page
{
MyOneWayService.OneWayWebService objProxy = null;
string strTimeElapsed = string.Empty;
protected void Page_Load(object sender, EventArgs e)
{
}
protected void btnClick_Click(object sender, EventArgs e)
{
Stopwatch objStopWatch = new Stopwatch();
objProxy = new MyOneWayService.OneWayWebService();
objProxy.HelloWorldOneWayCompleted += new MyOneWayService.HelloWorldOneWayCompletedEventHandler(objProxy_HelloWorldOneWayCompleted);
objStopWatch.Reset();
objStopWatch.Start();
objProxy.HelloWorldOneWayAsync(Convert.ToInt32(txtWaitTime.Text.Trim()));
strTimeElapsed = objStopWatch.ElapsedMilliseconds.ToString();
}
void objProxy_HelloWorldOneWayCompleted(object sender, System.ComponentModel.AsyncCompletedEventArgs e)
{
lblResult.Text = "Fired and Forgot.....!!!!! Took ' "+strTimeElapsed+" 'to Complete Execution";
}
}
}
现在运行应用程序……我们的页面将如下所示
在此页面上,我们需要做的是在文本框中输入一个整数值,然后等待响应到来……
我们期望的是,如果我们输入 10000 毫秒,根据我们的 Web 服务方法,它将花费 10000 毫秒来完成执行并返回。但我们所做的是,只是触发 Web 服务方法,然后在不等待 Web 方法完成执行的情况下返回到应用程序,对吧?
作为第一步,请执行该应用程序
在文本框中输入 10000,然后点击 GO,看看会发生什么……。
结果将是一个错误,类似





是的,AsyncCompletedEventArgs 的 Error 属性会给我们错误信息。


在这里,我将从另一个按钮点击事件调用新创建的 Web 方法。

查看执行时间和返回控制权所花费时间的区别。
