|
|
|
start date: Wed, 11 Jul 2007 11:12:21 -0400,
posted on: microsoft.public.dotnet.framework.aspnet.webservices
back
| Thread Index |
|
1
lucius am
|
|
2
John Saunders [MVP] john.saunders at trizetto.com
|
|
3
(Steven Cheng[MSFT])
|
|
4
(Steven Cheng[MSFT])
|
|
5
lucius am
|
|
6
(Steven Cheng[MSFT])
|
|
7
lucius am
|
Asynchronous Call Pattern Problem #2
My async web method does not seem to be truly asynchronous. My
webmethod is supposed to immediately return "nothing" to a calling
client while it makes its own webservice call to another remote thing.
Could someone tell me how to make this better? It seems like my
webmethod is still holding up the client while it makes its own remote
call instead of immediately returning.
public object prevstate;
public asyncstub myasyncstub;
public delegate List<BaseCommand> asyncstub( Invoker commandinvoker ,
List<BaseCommand> commandlist );
public List<BaseCommand> InvokerExec( Invoker commandinvoker ,
List<BaseCommand> commandlist )
{
using ( commandinvoker )
{
foreach ( BaseCommand command in commandlist )
{
// command has a "Do()" method that does the remote WS
call...
commandinvoker.ExecuteCommand( command );
// this is where the present web service hangs until the
remote web service completes
}
}
return commandlist;
}
public class invokerexecstate
{
public object prevstate;
public asyncstub myasyncstub;
}
[WebMethod]
public IAsyncResult BeginReq( string requestthing , AsyncCallback
asyncCallBack , object memstore )
{
List<BaseCommand> wantedCommands = new List<BaseCommand>();
MyCommand commandinstance = new MyCommand(requestthing);
wantedCommands.Add( commandinstance );
Invoker commandinvoker = new Invoker();
myasyncstub = new asyncstub( InvokerExec );
invokerexecstate localstate = new invokerexecstate();
localstate.prevstate = memstore;
localstate.myasyncstub = myasyncstub;
return myasyncstub.BeginInvoke( commandinvoker ,
wantedCommands , asyncCallBack , localstate );
}
[WebMethod]
public void EndReq( IAsyncResult completedResult )
{
invokerexecstate localstate =
(invokerexecstate)completedResult.AsyncState;
List<BaseCommand> completedCommands =
(List<BaseCommand>)localstate.myasyncstub.EndInvoke( completedResult
);
}
Date:Wed, 11 Jul 2007 11:12:21 -0400
Author:
|
Re: Asynchronous Call Pattern Problem #2
"lucius" <lucius@newsgroup.nospam> wrote in message
news:2qs993l9t7v26o5pvvqlvdjq5t3qonnpch@4ax.com...
>
>
> My async web method does not seem to be truly asynchronous. My
> webmethod is supposed to immediately return "nothing" to a calling
> client while it makes its own webservice call to another remote thing.
>
> Could someone tell me how to make this better? It seems like my
> webmethod is still holding up the client while it makes its own remote
> call instead of immediately returning.
>
>
>
> public object prevstate;
> public asyncstub myasyncstub;
> public delegate List<BaseCommand> asyncstub( Invoker commandinvoker ,
> List<BaseCommand> commandlist );
> public List<BaseCommand> InvokerExec( Invoker commandinvoker ,
> List<BaseCommand> commandlist )
> {
> using ( commandinvoker )
> {
> foreach ( BaseCommand command in commandlist )
> {
> // command has a "Do()" method that does the remote WS
> call...
> commandinvoker.ExecuteCommand( command );
> // this is where the present web service hangs until the
> remote web service completes
> }
> }
> return commandlist;
> }
>
> public class invokerexecstate
> {
> public object prevstate;
> public asyncstub myasyncstub;
> }
>
>
>
> [WebMethod]
> public IAsyncResult BeginReq( string requestthing , AsyncCallback
> asyncCallBack , object memstore )
> {
> List<BaseCommand> wantedCommands = new List<BaseCommand>();
> MyCommand commandinstance = new MyCommand(requestthing);
> wantedCommands.Add( commandinstance );
> Invoker commandinvoker = new Invoker();
> myasyncstub = new asyncstub( InvokerExec );
> invokerexecstate localstate = new invokerexecstate();
> localstate.prevstate = memstore;
> localstate.myasyncstub = myasyncstub;
> return myasyncstub.BeginInvoke( commandinvoker ,
> wantedCommands , asyncCallBack , localstate );
> }
>
>
> [WebMethod]
> public void EndReq( IAsyncResult completedResult )
> {
> invokerexecstate localstate =
> (invokerexecstate)completedResult.AsyncState;
> List<BaseCommand> completedCommands =
> (List<BaseCommand>)localstate.myasyncstub.EndInvoke( completedResult
> );
> }
Can you simplify this example? Your problem probably has nothing to do with
your BaseCommand class, for instance, so can you abstract that out?
--
John Saunders [MVP]
Date:Wed, 11 Jul 2007 11:37:06 -0400
Author:
|
Re: Asynchronous Call Pattern Problem #2
Hi Lucius,
As for the Asynchronous webmethod execution pattern, I still think doesn't
quite align to the current ASP.NET webservcie execution mode. The
IAsyncResult asynchronous pattern in .net framework is designed for
in-memory application code rather than distributed application. For
ASP.NET webservice, the current supported async appraoch is use the
client-side webservice proxy's BeginXXX method to issue the service
request asynchronously (however, the SOAP messages still arrive at
server-side and be processed synchronously). I'm not sure where you get
the idea that you can use the IAsyncResult pattern in webservcie like the
code you provided, so far I haven't seen any documentation or tutorial on
this. BTW, as John has suggested, you can use a simplified one to
demonstrate the behavior.
Sincerely,
Steven Cheng
Microsoft MSDN Online Support Lead
This posting is provided "AS IS" with no warranties, and confers no rights.
Date:Thu, 12 Jul 2007 09:05:12 GMT
Author:
|
Re: Asynchronous Call Pattern Problem #2
Hi Lucius,
Any progress on this or if you have any further question need help, please
feel free to post here.
Sincerely,
Steven Cheng
Microsoft MSDN Online Support Lead
This posting is provided "AS IS" with no warranties, and confers no rights.
Date:Mon, 16 Jul 2007 13:37:39 GMT
Author:
|
Re: Asynchronous Call Pattern Problem #2
Then I am not sure you understand my issue. What matters to me the
most is that my web service client gets an immediate return for any
asynchronous webservice call; my problem is that my code appears to
always run synchronously even though I am implementing an asynchronous
call pattern.
I looked at the following examples and samples:
At Your Service: Performance Considerations for Making Web Service
Calls from ASPX Pages
http://msdn2.microsoft.com/en-us/library/aa480507.aspx
Server-Side Asynchronous Methods for ASP.NET and WinFX
http://www.codeproject.com/cs/webservices/asyncws.asp
Access Web Services Asynchronously in .NET Design Patterns
http://www.codeproject.com/cs/webservices/wsasync.asp
Web Service optimization
http://www.codeproject.com/soap/webserviceoptimization.asp
Re: Abort an Asyncronous Web Service Call
http://forums.microsoft.com/MSDN/ShowPost.aspx?PostID=597202&SiteID=1
From reading those, it appears to me that a webclient can make a call
to a web service and get an immediate "null" result, and the webclient
can then check the web service at a later time to pick up the result.
My webservice can then take a long time to do its work (for example
call another web service or do a complex data query). The main issue
for me is that the original calling client not be blocked after the
initial Begin request is made.
Please feel free to escalate this or redirect me, but I really need a
working code sample. I will modify what I last posted with a little
more streamlined example.
Thanks.
On Thu, 12 Jul 2007 09:05:12 GMT, stcheng@online.microsoft.com (Steven
Cheng[MSFT]) wrote:
>Hi Lucius,
>
>As for the Asynchronous webmethod execution pattern, I still think doesn't
>quite align to the current ASP.NET webservcie execution mode. The
>IAsyncResult asynchronous pattern in .net framework is designed for
>in-memory application code rather than distributed application. For
>ASP.NET webservice, the current supported async appraoch is use the
>client-side webservice proxy's BeginXXX method to issue the service
>request asynchronously (however, the SOAP messages still arrive at
>server-side and be processed synchronously). I'm not sure where you get
>the idea that you can use the IAsyncResult pattern in webservcie like the
>code you provided, so far I haven't seen any documentation or tutorial on
>this. BTW, as John has suggested, you can use a simplified one to
>demonstrate the behavior.
>
>Sincerely,
>
>Steven Cheng
>
>Microsoft MSDN Online Support Lead
>
>
>This posting is provided "AS IS" with no warranties, and confers no rights.
Date:Tue, 17 Jul 2007 19:43:01 -0400
Author:
|
Re: Asynchronous Call Pattern Problem #2
Here is a sample of the entire .asmx.cs, hopefully it will be a little
clearer.
Thanks for looking again.
In this hopefully cleaned-up example, webservice client will call
"MyReq" and pass a semicolon-delimited string. The string will be
broken up and new DataSets will be created. The DataSets will be
populated by an instance of the "Invoker" class. The population can be
a very lenghy operation. The webservice client will get an immediate
return of "nothing" and can do other work while the webservice server
does its job. When the webservice server (Invoker instance) is done,
the result will be put into Application Cache. The client can then use
a different webmethod (not shown in this code) to get the data from
Application Cache and use it.
I was hoping to implement Invoker's work asynchronously. But it
appears that the caller is being blocked and has to wait for the work
to complete.
using System;
using System.Collections;
using System.Collections.Generic;
using System.ComponentModel;
using System.Configuration;
using System.Data;
using System.Globalization;
using System.Reflection;
using System.Runtime.Remoting.Messaging;
using System.Web;
using System.Web.Caching;
using System.Web.Services;
using System.Web.Services.Protocols;
using System.Xml;
[WebService( Namespace = "http://myisht.com/testws" )]
[WebServiceBinding( ConformsTo = WsiProfiles.BasicProfile1_1 )]
[ToolboxItem( false )]
public class MyOps : BaseWebService
{
public object prevInvokerState;
public InvokerStub transExecuteAsyncStub;
public delegate List<DataSet> InvokerStub( Invoker transInvoker ,
List<DataSet> setList );
public List<DataSet> TransInvokerExecute( Invoker transInvoker ,
List<DataSet> setList )
{
using ( transInvoker )
{
foreach ( DataSet dataSet in setList )
{
transInvoker.DoWork( dataSet );
// the above line might make a web service call to a Java WS in
Europe and populate the DataSet
// the above line might make a local SQL Server call and
populate the DataSet
// it does not matter what the call does, it will be lenghty and
I do not want the client to wait
// transInvoker.DoWork is not "running in the background", it is
blocking, making the client wait for it to finish.
}
}
return setList;
}
public class TransInvokerExecutionState
{
public object prevInvokerState;
public InvokerStub transExecuteAsyncStub;
}
[WebMethodAttribute]
public IAsyncResult BeginMyReq( string requestValues , AsyncCallback
asyncCallBack , object memoryStateStorage )
{
List<DataSet> setList = new List<DataSet>();
string[] requestData = requestValues.Split( ';' );
for ( int rdC = 0 ; rdC < requestData.Length ; rdC++ )
{
setList.Add( new DataSet(requestData[rdC]) );
}
// The DataSet has a name and Invoker will populate it based on the
name
Invoker transInvoker = new Invoker();
transExecuteAsyncStub = new InvokerStub( TransInvokerExecute );
TransInvokerExecutionState transLocalState = new
TransInvokerExecutionState();
transLocalState.prevInvokerState = memoryStateStorage;
transLocalState.transExecuteAsyncStub = transExecuteAsyncStub;
return transExecuteAsyncStub.BeginInvoke( transInvoker , setList ,
asyncCallBack , transLocalState );
}
[WebMethodAttribute]
public void EndMyReq( IAsyncResult completedResult )
{
TransInvokerExecutionState transLocalState =
(TransInvokerExecutionState)completedResult.AsyncState;
List<DataSet> completedList =
(List<DataSet>)transLocalState.transExecuteAsyncStub.EndInvoke(
completedResult );
Global.AddToCache( completedList );
}
}
Date:Tue, 17 Jul 2007 20:05:43 -0400
Author:
|
Re: Asynchronous Call Pattern Problem #2
Hi Lucius,
Thanks for your reply.
I have viewed the following two articles mentioned in your last message:
http://msdn2.microsoft.com/en-us/library/aa480507.aspx
http://www.codeproject.com/cs/webservices/wsasync.asp
Actually, both of the articles mainly introduce the asynchronous webservice
method call at client-side(the webservice's client proxy) through the
Beginxxx and Endxxx methods.
And the server-side asynchronous it mentioned is also used at
client-side/consumer, that is using the ASP.NET 2.0 page's async handler
feature. Anyway, at webservice's server-side code engine, there is no
asynchronous execution in all these solutions. To illustrate this further,
we can divide the webservice call into the below stages:
1. client-side proxy call webmethod
2. webservice request SOAP message is actually sent from client to server
3. server-side service receive SOAP message and deserizlie it to webmethod
call.
4. server-side execute method call and return the result as SOAP response
So far all the asynchronous pattern provided in those articles are
implemented at the 1,2 stage, for server-side execution, it just recieve
requests from client and process it synchronouly.
Sincerely,
Steven Cheng
Microsoft MSDN Online Support Lead
This posting is provided "AS IS" with no warranties, and confers no rights.
Date:Wed, 18 Jul 2007 05:44:07 GMT
Author:
|
|
|