Asynchronous Web Services


So far in this chapter, you have developed and utilized Web services synchronously, using HTTP as the main protocol for communication. This may be a good enough requirement for some of the simple Web services that we have used as an illustration in this chapter, but in the real world, Web services would typically be used to interface with back-end systems. A number of these back-end systems are not always available and many have longer process times. In scenarios like those, you would typically want to utilize Web services in an asynchronous fashion. Your current program can continue with the current course of execution and after the result is returned, the Web service can provide a call-back mechanism to the calling application. In this section, you utilize the .NET Framework asynchronous programming features (see Figure 9.11) to develop asynchronous Web services.

Figure 9.11. Invoking Web services asynchronously.

Developing asynchronous Web services involves using the design principle of having two matching WebMethods that utilize the Begin<> and End<> pattern (Listing 9.6). Also, you need to consider any data that needs to be passed between the invocations to maintain the proper state.

Listing 9.6 Asynchronous Web Services
 <%@ WebService Language="C#" Class="hks.AsyncService"%> using System; using System.Web; using System.Web.Services; using System.EnterpriseServices; namespace hks {    [WebService(Namespace="http://www.hiteshseth.com/webservices")]    public class AsyncService    {           public delegate string AsyncStub(String input);           public string AsyncMethod(String input)           {        // the actual Long Running Method Business Logic Logic        System.Threading.Thread.Sleep(10000);             return "Success (Input="+input+")";           }           public class ServiceState           {              public object previousState;              public AsyncStub asyncStub;           }           [WebMethod]           public IAsyncResult BeginAsyncMethod(String input,               AsyncCallback cb, Object o)           {               AsyncStub stub = new AsyncStub(AsyncMethod);               ServiceState state = new ServiceState();               state.previousState = o;               state.asyncStub = stub;               return stub.BeginInvoke(input, cb, state);           }          [WebMethod]          public string EndAsyncMethod(IAsyncResult call)          {               ServiceState ss = (ServiceState) call.AsyncState;               return ss.asyncStub.EndInvoke(call);          }        } } 

After the Web services have been developed, you can use delegates to pass a callback function handler for displaying the Web service invocation result (see Listing 9.7).

Listing 9.7 Using an Asynchronous Web Service
 using System; using System.Drawing; using System.Collections; using System.ComponentModel; using System.Windows.Forms; using System.Data; namespace AsyncApplication {    public class AsyncInvoke : Form    {       private localhost.AsyncService proxy;       private Label inputLabel;       private TextBox inputTextBox;       private Button asyncInvokeButton;       private StatusBar resultLabel;       private Container components = null;       public AsyncInvoke()       {          InitializeComponent();       }       protected override void Dispose( bool disposing )       {          if( disposing )          {             if (components != null)             {                components.Dispose();             }          }          base.Dispose( disposing );       }       private void InitializeComponent()       {          this.inputLabel = new Label();          this.inputTextBox = new TextBox();          this.asyncInvokeButton = new Button();          this.resultLabel = new StatusBar();          this.SuspendLayout();          //          // inputLabel          //          this.inputLabel.Location = new Point(8, 18);          this.inputLabel.Name = "inputLabel";          this.inputLabel.Size = new Size(96, 16);          this.inputLabel.TabIndex = 0;          this.inputLabel.Text = "Input";          //          // inputTextBox          //          this.inputTextBox.Anchor =            ((AnchorStyles)(((AnchorStyles.Top               AnchorStyles.Left)  AnchorStyles.Right)));          this.inputTextBox.Location = new Point(112, 16);          this.inputTextBox.Name = "inputTextBox";          this.inputTextBox.Size = new Size(176, 20);          this.inputTextBox.TabIndex = 1;          this.inputTextBox.Text = "Input Text ...";          //          // asyncInvokeButton          //          this.asyncInvokeButton.Anchor =            ((AnchorStyles)((AnchorStyles.Bottom  AnchorStyles.Right)));          this.asyncInvokeButton.Location = new Point(160, 48);          this.asyncInvokeButton.Name = "asyncInvokeButton";          this.asyncInvokeButton.Size = new Size(128, 24);          this.asyncInvokeButton.TabIndex = 2;          this.asyncInvokeButton.Text = "Async Invoke";          this.asyncInvokeButton.Click += new             System.EventHandler(this.asyncInvokeButton_Click);          //          // resultLabel          //          this.resultLabel.Anchor =            ((AnchorStyles)((AnchorStyles.Bottom  AnchorStyles.Right)));          this.resultLabel.Location = new Point(0, 88);          this.resultLabel.Name = "resultLabel";          this.resultLabel.Size = new Size(288, 24);          this.resultLabel.TabIndex = 3;          //          // AsyncInvoke          //          this.AutoScaleBaseSize = new Size(5, 13);          this.ClientSize = new Size(292, 117);          this.Controls.Add(this.resultLabel);          this.Controls.Add(this.asyncInvokeButton);          this.Controls.Add(this.inputTextBox);          this.Controls.Add(this.inputLabel);          this.Name = "AsyncInvoke";          this.Text = "Async Web Services Invoke Application";          this.ResumeLayout(false);       }       [STAThread]       static void Main()       {          Application.Run(new AsyncInvoke());       }       private delegate void MyDelegate(string response);       private void Callback(IAsyncResult result)       {          String response;          response = proxy.EndAsyncMethod(result);          resultLabel.Invoke(new            MyDelegate(DisplayResult),new object[] {response});       }       private void asyncInvokeButton_Click(object sender, System.EventArgs e)       {          resultLabel.Text = "";          proxy = new localhost.AsyncService();          proxy.BeginAsyncMethod(inputTextBox.Text,             new AsyncCallback(Callback),null);       }       private void DisplayResult(String response)       {          resultLabel.Text = response;       }        } } 


Microsoft.Net Kick Start
Microsoft .NET Kick Start
ISBN: 0672325748
EAN: 2147483647
Year: 2003
Pages: 195
Authors: Hitesh Seth

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net