Cancel async web service calls - c#

I need to be able to cancel async calls made to my webservice. One solution I have is to use manage my own threads, and use synchronous methods from the SOAP client. This works fine and it needs some more fine grained thread management.
If I used any of these two patterns provided from adding a web service reference, say:
var Client = new ASL_WS.SvcSoapClient()
IAsyncResult result = Client.BeginAuthenticateUser(Email, Password, new AsyncCallback(AuthCompleted));
or
var Client = new ASL_WS.SvcSoapClient()
Client.AuthenticateUserCompleted += AuthCompleted;
Client.AuthenticateUserAsync(Email, Passsword);
do any of these two patterns give me a way of cancelling the request? One use case could be: a user logs in, but wants to cancel before the authenticate call completes.
Of course, I could implement this differently by modifying the asyncState passed to these calls, and setting it to disable UI update, but it's not what I'm looking for.
Could I just just cancel all outstanding operations. Does Client.Abort() cancel such operations. What if there are many async requests, are all cancelled? Are there any other API methods that can do this?

Yes, you can use Abort method but keep below notes in mind. You can also use CancelAsync.
Abort notes: http://msdn.microsoft.com/en-us/library/aa480512.aspx
When you call the Abort method, any outstanding requests will still complete, but they will complete with a fault. This means that if you are using callbacks, your callback function will still be called for each outstanding request . When the EndInvoke method is called, or in our case, the wrapper function EndDelayedResponse, then a fault will be generated indicating that the underlying connection has been closed.
CancelAsync example: http://www.codeproject.com/KB/cpp/wsasync.aspx

Related

System.Net.WebClient - should I use Async

I have a C# web application that makes a web service call, then renders a page for a browser. Following this advice, I chose to use System.Net.WebClient for the request because it had a succint interface and all the control I needed.
WebClient offers me async versions of all the download methods. Should I use them? I don't care if the current user waits. I need the web service result before I can render the page, and I have nothing else to be doing (for her) in the meantime. However I really do care if my server is tied up while one user's web service call completes. If this was javascript, a synchronous web request on the main thread would hold up at least the whole window. Is this the case in asp.net? For reasons outta my control, my web service request is at the bottom of a pile of 15 method calls. Dot I have to convert them all to async to see any advantage?
Generally speaking, async IO won't yield faster per-request response, but in theory it can increase throughput.
public async Task<IActionResult> YourWebApiMethod() {
// at this point thread serving this request is returned back to threadpool and
// awailable to serve other requests
var result = await Call3ptyService();
// once IO is finished we grab new thread from thread pool to finish the job
return result;
}
// thread serving this request is allocated for duration of whole operation
public IActionResult YourWebApiMethod() {
return Call3ptyService().Result;
}
You have only so-many threads in thread pool, if every single one is busy waiting for external service; your web server will stop serving requests. As for your particular problem - try it and you'll find out.

How to call a web service in "fire and forget" way from ASP.Net

I have a web service that I want to call from one of my asp.net classes.
I can call my web service successfully.But now I need to call this service asynchronously. I need to call it and NOT wait for the service to complete execution. I don't need to process a response from the service and don't need to verify if the service executed successfully. All I want is to be able to call the service and be free to do other things.
You need to consume web service asynchronously.
Goto and check
AddServiceReference -> Advance -> generate asynchronous operations.
after this async callback events will be available to you for every method
Suppose you have ABC method in you service when you will consume it by as sync these methods will be available to you in your application
1>ABC (fire and wait for output)
2>ABCAsync(fire and forget)
3>ABC callback event(get fired <if ABCAsync is called> when data available in your application)
One way to implement a fire-and-forget approach is to use the IsOneWay property on the OperationContract attribute, like this:
[OperationContract(IsOneWay=true)]
public void SomeMethod(string someValue);
When set to true, the operation won't return a message. Note that methods marked as one-way cannot have return types or ref or out parameters (which makes sense). It also should not be confused with asynchronous calls, because it's not the same thing (in fact, a one-way call can block on the client if it takes a while to get a connection, for example).
See OperationContractAttribute.IsOneWay Property for more information.
Have you tried this:?
http://msdn.microsoft.com/en-us/library/bb885132(v=vs.110).aspx
this is another way to do it, check it out.

How to Cancel a RIA Services LoadOperation

I am using RIA services in a Silverlight project. I am using the LoadOperation class on the client side to load some data from the server.
In the process of loading that data the request might be superseded by a newer request for different data. This is based on multiple LoadOperations being made to the server, then the user clicking a cancel button.
If I take my LoadOperation and call the 'Cancel' method on it, the operation seems to cancel, but the server side code is not stopped, and using fiddler I can see that the operation completes and an HTTP status code of 200 is returned.
When you call 'Cancel' what does that do on the server, I would expect it to call a ThreadAbortException or something like that? Can this be improved?
So I had a look at the decompiled RIA Services source and it seems like the cancel is client side only. No change to the server-side process is made.
Basically when you run operation.Cancel(), it makes sure the operation can be canceled (operation.CanCancel), and then marks it as canceled, and triggers the completion action.
This means that the server-side operation still continues, but nothing is done with the response client side when it completes
Once the operation has completed, you'll need to check the operation.IsCanceled property to see if that operation was canceled. If so, just ignore the result.
From what I understand cancel of serverside execution using the loadoperation is not available.
you could tough run your own cancel impelmentation:
(depending on if you are using DomainService base or LinqToEntitiesDomainService base the impelmentation will variate)
sevice side
in your service method start the load in a new thread
put that thread object in the session
your thread object should be in a way that you can cancel the DbConnection...
perpare a service method (Invoke) to Cancel the currently executing
thread object registered in the session, and remove it from the session
client side
call cancel on the LoadOperation object and invoke the cancel request.
one caveat is that you comment out the OnSessionStart and stop in global.asax in order
to execute ria services in a multithreaded way per user else each request will wait till a previous request is finished (this has to do with ria service threads and not our thread object)
hope this helps
best regards
PS: we also use a similar solution for pessimistic lock with RIA Services and EntityFramework, ...

Block thread until WCF callback is raised?

Is it possible to wait on a callback in WCF? Given this article, I will raise a callback in my WCF service, but I want the client (a seperate application) to only proceed (ie go to the next line of code, e.g. close a form etc, after the callback is raised. So I need to block until the callback is raised.
How could I do this?
Instead of using callbacks, you could call the service synchronously from the client.
If the client does not require any data to be returned, you could return a void, and the client will still wait for the call to complete.

How to set Async Page Directive Dynamically so Async Methods work

I am writing some Utility code to send off emails Async.
var mailClient = new SmtpClient(smtpHost);
mailClient.SendCompleted += new SendCompletedEventHandler(mailClient_SendCompleted);
using (var mailMessage = new MailMessage())
{
if (!((System.Web.UI.Page)HttpContext.Current.CurrentHandler).IsAsync)
{
// set to Async????
}
mailClient.SendAsync(mailMessage, new { EmailID });
}
But I get errors because my Pages don't have Async="true" in the page directives.
here is the standard error that you get:
"Asynchronous operations are not allowed in this context. Page starting an
asynchronous operation has to have the Async attribute set to true and an
asynchronous operation can only be started on a page prior to
PreRenderComplete event."
I read this: (last paragraph )
http://msdn.microsoft.com/en-us/magazine/cc163725.aspx
A final point to keep in mind as you
build asynchronous pages is that you
should not launch asynchronous
operations that borrow from the same
thread pool that ASP.NET uses. For
example, calling
ThreadPool.QueueUserWorkItem at a
page's asynchronous point is
counterproductive because that method
draws from the thread pool, resulting
in a net gain of zero threads for
processing requests. By contrast,
calling asynchronous methods built
into the Framework, methods such as
HttpWebRequest.BeginGetResponse and
SqlCommand.BeginExecuteReader, is
generally considered to be safe
because those methods tend to use
completion ports to implement
asynchronous behavior.
Questions:
1) How can I update the page to be Async in my c# code?
2) If I can't what is the down side with forcing all my pages to be Async=true?
3) Is there an even better way to thread my task without being "counterproductive"?
How many different pages do you need to send mail from?
Also, what error did you get when you tried to send async? Please edit your question to contain the entire exception.
Consider creating a single (async) page to send email from. You can call that page by using Server.Transfer, and have it redirect back to your desired page when done.
Finally, if you're sending so many emails that you lose performance when sending mail synchronously, then perhaps you should create a Windows Service to send the actual email. Your ASP.NET page would queue a request to this service (through MSMQ, or WCF) to have the service send the email.

Categories