Call WebService Asynchronously

Source: Internet
Author: User

In many cases, we may use Asynchronous WebService calls. The advantage of using asynchronous mode is non-blocking. Of course, it also increases programming difficulty. With asynchronous programming, we can call remote services, query call statuses, or cancel calls.

Let's take the code instance as an example to explain
First, use vs2k3 to create a WebService. Assume it is a service that provides stock information. Here, the processing is relatively simple. It takes a long time to simulate a service call.
Namespace stockservice
{
/// <Summary>
/// Summary of service1.
/// </Summary>
Public class stockprice: system. Web. Services. WebService
{
Public stockprice ()
{
// Codegen: This call is an ASP. NET web service designer.

Required
Initializecomponent ();
}

# Code generated by the region component designer

// Required by the Web Service designer
Private icontainer components = NULL;

/// <Summary>
/// The designer supports the required methods-do not use the code editor to modify
/// Content of this method.
/// </Summary>
Private void initializecomponent ()
{
}

/// <Summary>
/// Clear all resources in use.
/// </Summary>
Protected override void dispose (bool disposing)
{
If (disposing & components! = NULL)
{
Components. Dispose ();
}
Base. Dispose (disposing );
}

# Endregion

[Webmethod]
Public double getstockprice (string stocksymbol)
{
// Here we conduct simulated processing, and the thread is suspended for 5 seconds
Thread. Sleep (5000 );
Return new random (). nextdouble () + 15.0;
}
[Webmethod]
Public double getstockprice1 (string stocksymbol)
{
// Here we conduct simulated processing, and the thread is suspended for 5 seconds
Thread. Sleep (5000 );
Return new random (). nextdouble () + 15.0;
}
[Webmethod]
Public double getstockprice2 (string stocksymbol)
{
// Here we conduct simulated processing, and the thread is suspended for 5 seconds
Thread. Sleep (5000 );
Return new random (). nextdouble () + 15.0;
}

}
}

Then we create a winform program to act as the client to call the WebService we just created. There are many ways to Implement Asynchronous calls (including creating a thread to call the service, and using delegate to implement Event Callback after the service is complete ). This method is excluded first. Because when you add a web reference to a local project, the code for asynchronous calls has been implemented in the proxy class.
Public class form2: system. Windows. Forms. Form
{
Private localhost. stockprice m_stockservice;
Private iasyncresult m_handle;
Private system. Windows. Forms. Button button1;
Private system. Windows. Forms. Button button2;
Private system. Windows. Forms. Button button3;
Private system. Windows. Forms. Button button4;
Private system. Windows. Forms. textbox MessageBox;
Private system. Windows. Forms. Button button5;
Private system. Windows. Forms. Button button6;

/// <Summary>
/// Required designer variables.
/// </Summary>
Private system. componentmodel. Container components = NULL;

Public form2 ()
{
//
// Required for Windows Form Designer support
//
Initializecomponent ();

//
// Todo: add Any constructor code after initializecomponent calls
//
}

/// <Summary>
/// Clear all resources in use.
/// </Summary>
Protected override void dispose (bool disposing)
{
If (disposing)
{
If (components! = NULL)
{
Components. Dispose ();
}
}
Base. Dispose (disposing );
}

# Region code generated by Windows Form Designer
/// <Summary>
/// The designer supports the required methods-do not use the code editor to modify
/// Content of this method.
/// </Summary>
Private void initializecomponent ()
{
This. MessageBox = new system. Windows. Forms. Textbox ();
This. button1 = new system. Windows. Forms. Button ();
This. button2 = new system. Windows. Forms. Button ();
This. button3 = new system. Windows. Forms. Button ();
This. button4 = new system. Windows. Forms. Button ();
This. button5 = new system. Windows. Forms. Button ();
This. button6 = new system. Windows. Forms. Button ();
This. suspendlayout ();
//
// MessageBox
//
This. MessageBox. Location = new system. Drawing. Point (16, 8 );
This. MessageBox. multiline = true;
This. MessageBox. Name = "MessageBox ";
This. MessageBox. scrollbars = system. Windows. Forms. scrollbars. vertical;
This. MessageBox. size = new system. Drawing. Size (656,320 );
This. MessageBox. tabindex = 0;
This. MessageBox. Text = "";
//
// Button1
//
This. button1.location = new system. Drawing. Point (24,344 );
This. button1.name = "button1 ";
This. button1.tabindex = 1;
This. button1.text = "call ";
This. button1.click + = new system. eventhandler (this. button#click );
//
// Button2
//
This. button2.location = new system. Drawing. Point (128,344 );
This. button2.name = "button2 ";
This. button2.tabindex = 2;
This. button2.text = "polling ";
This. button2.click + = new system. eventhandler (this. button2_click );
//
// Button3
//
This. button3.location = new system. Drawing. Point (240,344 );
This. button3.name = "button3 ";
This. button3.tabindex = 3;
This. button3.text = "Abort ";
This. button3.click + = new system. eventhandler (this. button3_click );
//
// Button4
//
This. button4.location = new system. Drawing. Point (352,344 );
This. button4.name = "button4 ";
This. button4.size = new system. Drawing. Size (96, 23 );
This. button4.tabindex = 4;
This. button4.text = "waiting for asynchronous operations ";
This. button4.click + = new system. eventhandler (this. button4_click );
//
// Button5
//
This. button5.location = new system. Drawing. Point (464,344 );
This. button5.name = "button5 ";
This. button5.size = new system. Drawing. Size (120, 23 );
This. button5.tabindex = 5;
This. button5.text = "three services are called at a time ";
This. button5.click + = new system. eventhandler (this. button5_click );
//
// Button6
//
This. button6.location = new system. Drawing. Point (608,344 );
This. button6.name = "button6 ";
This. button6.tabindex = 6;
This. button6.text = "Callback processing ";
This. button6.click + = new system. eventhandler (this. button6_click );
//
// Form2
//
This. autoscalebasesize = new system. Drawing. Size (6, 14 );
This. clientsize = new system. Drawing. Size (696,477 );
This. Controls. Add (this. button6 );
This. Controls. Add (this. button5 );
This. Controls. Add (this. button4 );
This. Controls. Add (this. button3 );
This. Controls. Add (this. button2 );
This. Controls. Add (this. button1 );
This. Controls. Add (this. MessageBox );
This. Name = "form2 ";
This. Text = "form2 ";
This. Load + = new system. eventhandler (this. form2_load );
This. resumelayout (false );

}
# Endregion

Private void form2_load (Object sender, system. eventargs E)
{

}

// You call begingetstockprice () to obtain an object with the iasyncresult interface.
// It provides the iscompleted attribute. When the value is "true,
// You can call endgetstockprice () to obtain the function running result.
// More importantly, you can "discard abort" calls during asynchronous calls.
// The following program section uses three buttons to indicate how to use Asynchronous calls, check whether the call is complete, and discard the call.

// Call webmethod Asynchronously
Private void button#click (Object sender, system. eventargs E)
{
M_stockservice = new localhost. stockprice ();
M_handle = m_stockservice.begingetstockprice ("IBM", null, null );
MessageBox. Text + = "calling Web Service." + system. environment. newline;

}
// Check whether the asynchronous call is complete. If the call is complete, retrieve the call result.
Private void button2_click (Object sender, system. eventargs E)
{
If (m_handle = NULL)
{
MessageBox. Text + = "no service is called! "+ System. environment. newline;
Return;
}
If (m_handle.iscompleted = false)
MessageBox. Text + = "the service is being called" + system. environment. newline;
Else
{
Double price = m_stockservice.endgetstockprice (m_handle );
MessageBox. Text + = "amount:" + Price + system. environment. newline;
}

}

// Discard asynchronous call
Private void button3_click (Object sender, system. eventargs E)
{
If (m_handle! = NULL)
{
Webclientasyncresult result = (webclientasyncresult) m_handle;
Result. Abort ();
M_handle = NULL;
}
MessageBox. Text + = "the service is terminated by the user" + system. environment. newline;

}

// Use waithandle
// You call begingetstockprice () to obtain an object with the iasyncresult interface.
// It provides asyncwaithandle attributes. Calling its waitone () function can block the program until another thread function is called.
// The Program continues to run.
Private void button4_click (Object sender, system. eventargs E)
{
If (this. m_stockservice = NULL)
M_stockservice = new localhost. stockprice ();
M_handle = m_stockservice.begingetstockprice ("IBM", null, null );
MessageBox. Text + = "Calling Service" + system. environment. newline;
M_handle.asyncwaithandle.waitone ();
Double price = m_stockservice.endgetstockprice (m_handle );
MessageBox. Text + = "amount:" + Price + system. environment. newline;

}

// From the symptom point of view, you do not get any advantage over synchronous calls. The program is still in the "suspended" status while waiting.
// However, in some cases, "waiting" still has its own characteristics.
// For example, you can call three webmethods consecutively. If each function takes 5 seconds,
// Use synchronization for a total of 15 seconds. However, if asynchronous mode is used, you may only need to wait for 5 seconds.
// Of course, this requires the waitall () function provided by waithandle. As follows:
// Call three services at a time
Private void button5_click (Object sender, system. eventargs E)
{

If (this. m_stockservice = NULL)
M_stockservice = new localhost. stockprice ();
Iasyncresult [] handles = new iasyncresult [3];

MessageBox. Text + = "three services are called at a time: the start time is" + datetime. Now. tostring () + system. environment. newline;
Handles [0] = m_stockservice.begingetstockprice ("IBM", null, null );
Handles [1] = m_stockservice.begingetstockprice1 ("Ms", null, null );
Handles [2] = m_stockservice.begingetstockprice2 ("sun", null, null );

Waithandle [] waithandles = {
Handles [0]. asyncwaithandle,
Handles [1]. asyncwaithandle,
Handles [2]. asyncwaithandle };

// The function is blocked until all three functions are executed. The waitany () function is similar, but after a function is completed
// The program unblocks and continues to execute
Waithandle. waitall (waithandles );
MessageBox. Text + = "call completion time:" + datetime. Now. tostring () + system. environment. newline;
Double [] prices = new double [3];
For (INT I = 0; I <3; I ++)
{
Prices [I] = m_stockservice.endgetstockprice (handles [I]);
MessageBox. Text + = "amount:" + Prices [I] +
System. environment. newline;
}
MessageBox. Text + = "three services have been called:" + system. environment. newline;
}

// You may not be satisfied yet. Because after you call a function asynchronously, you must manually check whether the function has been executed,
// Or wait. Can I enable the function to automatically display results or perform other operations?
// The answer is "yes. The callback function does this.
Private void button6_click (Object sender, system. eventargs E)
{
If (this. m_stockservice = NULL)
M_stockservice = new localhost. stockprice ();
// Generate the callback function
Asynccallback cb = new asynccallback (this. Callback );
M_stockservice.begingetstockprice ("IBM", CB, datetime. Now );
MessageBox. Text + = "remote service called" + system. environment. newline;

}
Private void callback (iasyncresult handle)
{
Double price = m_stockservice.endgetstockprice (handle );
Lock (this)
{
MessageBox. Text + = "amount:" + Price + ". Request time:" +
Handle. asyncstate. tostring () + ", end time:" +
Datetime. Now. tostring () +
System. environment. newline;
}
}
}

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.