I am dealing with a web-service call that may take anywhere from a few seconds to several minutes to complete. It constructs the requested data and returns it. Right now for a long-running call into the WS the user interface (WinForms) becomes unresponsive; the user has no way to cancel the operation.
The ideal approach to solving this (I think) would be to break the operation into two web-service calls: first a request, second to get the status or available data.
But if the web-service structure cannot be changed, what is the best way to interrupt the web-service call?
UPDATE:
The WS call could be made asynchronously. If the user wants to cancel the operation, then I'd like to relieve the server of unfinished work (rather than letting the thread complete normally and throw away the response). Thread.Abort() is a possibility but I want to know if there is a better way.
The web services I am working with are WCF based. The operations are read-only, so there is nothing to undo if interrupted.
You can generate Asynchronous proxy class to implement this feature.
Please look at the following link for sample,
http://msdn.microsoft.com/en-us/library/wyd0d1e5(v=vs.100).aspx
Related
I have a question in regard to running synchronous operations in an API design. I understand fully running asynchronous in certain scenarios like this is the correct approach this is more a conceptual understanding. If I have an Angular front end where the user can call an API endpoint with Subscribe which passes a list of CustomerId's. In the API a synchronous ActionResult is called which then iterates through these customer id's and calls a synchronous database call that can take a good amount of time to complete for each call.
The question I have is does that actually lock up the service if another user takes an action in the same UI against the backend service will the service not respond until that other user action is complete? I am just trying to wrap my head around that concept does the service lock up in that case and the UI would not be responsive. Multitask programming of course is the way to handle this just conceptually.
Thanks for input.
what you are missing is:-
angular runs on client end it means that every user will have an instance running on his system and his local instance may fail and in a result that particular client's instance may fail.
If using asynchronous backend it also won't stop it may fail the process and respond accordingly(if all errors have been handled). In the worst-case scenario even if it fails server gets restarted as mostly it's monitored using process managers like pm2. which takes no time to restart it.
so basically nothing gets blocked until there is an issue on your server and server stops to respond.
I am working on SOAP-client in WCF to communicate with a self-hosted WCF service for remote controlling a piece of software that I am developing. This software has a very long running operation (lets call it Print) that will run for several minutes, perhaps up to an hour. I am trying to figure out how to implement the method Print given the following requirements:
The server should be able to raise FaultExceptions to the client, in case something goes wrong.
The client should be informed ASAP should the connection to the service be lost.
The server-side process of Print should continue to run if disconnected, so that the client can reconnect and continue to monitor the process and abort it if necessary.
Since I am new to WCF, I am unsure how to implement this. I currently see two alternatives:
Make Print an async method so that I can "fire and forget" it until it finishes or throws a FaultException. This seems straight-forward, but I see this "problem": There is a client-side request timeout in WCF with default value of 1 minute, which also applies to async methods (if I am not mistaken) and which I would therefore have to increase significantly. This seems a bit like a hack.
Implement the async behavior of Print myself by splitting its behavior into a non-async method StartPringing that starts a server-side task for printing and returns directly (or throws an exception in case something goes wrong) and a client-callback method PrintingFinished. I could then use the callback PrintingFinished to signal to the client, when the print-process has finished or a use an additional callback PrintingFailed to send an exceptions in case something goes wrong. This implementation would be "hidden" behind the async method Print, so that it behaves like any other async method that might throw an exception. Here I see the following challenge: I will have to implement the whole exception callback-stuff myself, to handle exceptions that occur after StartPringing has returned (from StartPringing itself I can throw FaultExceptions).
For both cases I will have to work out how to detect, when the connection is servered (which I am currently doing using a ping method on the service) and then somehow get that event to throw an exception from within the method Print. Implementation-wise this seems more aligned with alternative (2), since I need to already implement all the other event handlers for when the print-process finishes or an exception is thrown. However I am unsure how I would implement this for alternative (1).
So which one of the two alternatives is "better". By better I mean the following considerations:
1. Aligned with the "standard" way in WCF for implementing such a long running method.
2. Maintainability and extensibility.
If I should consider any other alternative, I would be grateful for any other suggestion.
For what I understand of your problem I think if you need a real async communication with reliability to use a message queue like MSMQ. You can use it with WCF : https://msdn.microsoft.com/en-us/library/ms789048(v=vs.110).aspx
Update
In your case, you can use a SOAP call to send print command to the server because it sync and you need to know if the server handle the request. After in the printing operation is long and async. When this operation finish (exception or not) it need to notify client(s). But client could be shutdown for example. For that communication a Message Queue is the solution, MQ ensure that the message will be transmit.
https://en.wikipedia.org/wiki/Message_queue
If you don't want use MSMQ, you can implement a web service on client side to be notified by the printing server, using for example a UUID to match call and notification in a map in memory or in a Data Base.
I've not dealt much with Async/threads/Tasks other than some web services.
I'm using MVC4. I have existing code which takes some time to run. It is using an existing method in the service layer, which uses various other the areas in further layers.
Essentially I was hoping to be able to make an ASync call from the Asynccontroller to that method. However it appears that I would need to change/create another method to implement all the Task & await keywords, quite a hefty job altering all the way down the chain.
Is it possible to call/'fire' a synchronous method in this manner?
I want the long process (creating some documents in the background) to continue running even if the user closes their browser. However if the user still has the browser open then I would like to return a notification to them.
Is there a better way to fire a background task to execute from the MVC Application?
I think you're trying to use async for something it cannot do. As I describe on my blog, async does not change the HTTP protocol.
Is it possible to call/'fire' a synchronous method in this manner?
Sort of. You can use Task.Run if you have CPU-bound work that you want to move off the UI thread in a desktop/mobile application. But there is no point in doing that in an ASP.NET MVC application.
I want the long process (creating some documents in the background) to continue running even if the user closes their browser. However if the user still has the browser open then I would like to return a notification to them.
The problem with this is that you'd be returning early from an ASP.NET request, and (as I describe on my blog), that's quite dangerous.
A proper solution would be to queue the work in a reliable queue (e.g., Azure queue or MSMQ), have an independent backend for processing (e.g., Azure worker role / web job or Win32 service), and use something like SignalR for notification.
As soon as you attempt to do work in an ASP.NET process without a request context, then you run into the danger that your process may exit without completing the work. If you are OK with this, then you can use the BackgroundTaskManager type from my blog above to minimize the chance of that happening (but keep in mind: it can still happen).
When i saw the first news about await, i was very excited and i thought many ways of using it.
One of these is to use it in my web framework to hide the asynchronous aspect of client/server exchanges like it's done in several frameworks.
So here is the deal:
I would like to write things like that:
{
Page p = new Page();
FormResponse response = await p.Show();
var field1 = reponse.inputField["input1"];
...
}
I would like the dev to be able to write this code on the server. As you guess p.Show() write in the HttpResponse the html code displaying the page with the form, and send the response to the client, so, the thread is
killed and i never reach the next instruction (FormResponse response =).
So here is my question:
Is there any way of doing such a thing ? I know await cut the code, pack it in a continuation, make the closure for us, and store it somewhere to call it back when p.Show() is done.
But here, the thread is going to be killed, and this is my code which recieve the submit response from Page which has to deal with it. So i have to restore the continuation that "await" created and execute it myself.
Am i getting high or is it possible ?
Edit : additional infos
I can explain a bit more, but we need an example.
Imagine you want to make an async call to a webservice, you just use await and then call the webs.
A webs doesn't display any page, it returns pieces of information and you can continue the next instructions, so with a webs we have : Client -> Server A [-callwebs-> Server B ->] Server A -> Client.
Now, imagine a webs wich has to display a user interface to grab some information from the user, we can call this kind of webs a UIwebs (a reusable interface called by several webapp),
it displays the ui, grabs the info, and sends it back to the caller.
So with a UI webs we have : Client -> Server A [-response_redirect-> Client -get-> Server B (here is the UIwebs, the client inputs whatever) -response_redirect-> Client -get-> ] Server A -> Client
What i put between brackets has to be handle in the way by the developper :
so for a classic webs, i can imagine the asynchronous page is "sleeping" waiting the webs to response, but with a UI webs we have to response à redirect to the client, so the page is done for asp.net, and SynchronizationContext says that there is no more async instruction to wait for.
In fact, my need here is the same as turning on the web server, and sending a request to it wich coule restore everything needed to execute the code just after the await.
Regards,
Julien
I'm not sure what the problem is.
If you have, e.g., ASP.NET asynchronous pages, then any top-level (async void) function will properly notify ASP.NET that the page is incomplete and release the thread. Later, the continuation will run on a (possibly another) thread, restore the request context, and finish the request.
The async design was carefully done to enable this exact behavior. In particular, async void increments the outstanding asynchronous operation count in SynchronizationContext, as I described in a recent MSDN article.
If you're running your own host (i.e., not using ASP.NET), then you'll have to implement SynchronizationContext. It's non-trivial but not extremely hard, either. Once this is done, async and await will "just work". :)
Updated answer in response to edit:
Keep in mind that await/async are just syntactical sugar; they don't enable anything that wasn't possible before - they just make it easier.
If I understand your situation correctly, you want a web service to return a UI and then respond to it. This is an inversion of how HTTP works, so you'd have to do some funky stuff with viewstate. I'll think about it...
I’m looking for the best way of using threads considering scalability and performance.
In my site I have two scenarios that need threading:
UI trigger: for example the user clicks a button, the server should read data from the DB and send some emails. Those actions take time and I don’t want the user request getting delayed. This scenario happens very frequently.
Background service: when the app starts it trigger a thread that run every 10 min, read from the DB and send emails.
The solutions I found:
A. Use thread pool - BeginInvoke:
This is what I use today for both scenarios.
It works fine, but it uses the same threads that serve the pages, so I think I may run into scalability issues, can this become a problem?
B. No use of the pool – ThreadStart:
I know starting a new thread takes more resources then using a thread pool.
Can this approach work better for my scenarios?
What is the best way to reuse the opened threads?
C. Custom thread pool:
Because my scenarios occurs frequently maybe the best way is to start a new thread pool?
Thanks.
I would personally put this into a different service. Make your UI action write to the database, and have a separate service which either polls the database or reacts to a trigger, and sends the emails at that point.
By separating it into a different service, you don't need to worry about AppDomain recycling etc - and you can put it on an entire different server if and when you want to. I think it'll give you a more flexible solution.
I do this kind of thing by calling a webservice, which then calls a method using a delegate asynchronously. The original webservice call returns a Guid to allow tracking of the processing.
For the first scenario use ASP.NET Asynchronous Pages. Async Pages are very good choice when it comes to scalability, because during async execution HTTP request thread is released and can be re-used.
I agree with Jon Skeet, that for second scenario you should use separate service - windows service is a good choice here.
Out of your three solutions, don't use BeginInvoke. As you said, it will have a negative impact on scalability.
Between the other two, if the tasks are truly background and the user isn't waiting for a response, then a single, permanent thread should do the job. A thread pool makes more sense when you have multiple tasks that should be executing in parallel.
However, keep in mind that web servers sometimes crash, AppPools recycle, etc. So if any of the queued work needs to be reliably executed, then moving it out of process is a probably a better idea (such as into a Windows Service). One way of doing that, which preserves the order of requests and maintains persistence, is to use Service Broker. You write the request to a Service Broker queue from your web tier (with an async request), and then read those messages from a service running on the same machine or a different one. You can also scale nicely that way by simply adding more instances of the service (or more threads in it).
In case it helps, I walk through using both a background thread and Service Broker in detail in my book, including code examples: Ultra-Fast ASP.NET.