I have a c# application and I want to fire off a webservice but I dont care about the response and I also dont care if it fails. At the moment i fire of the service async but i am getting an error when the call fails.
Is there anyway I can configure the app/webservice to stop it failing without rapping try catches around them (basiclly fire and forget)?
Thanks
Sp
Here is one idea:
Write your web service do that it returns 'success' right away, then fires off an async process that does the work.
You can also do this by creating a queue or something, where another process watches the queue and performs the work. Then the web service's only job, then, is to add an entry to the queue.
Related
I am writing an API using ASP.NET and I have some potentially long running code from the different end points. The system uses CQRS and Event Sourcing. A Command comes into to an end point and is then published as an event using MediatR. However the Handlers are potentially long running. Since some of the Requests coming in might be sent to multiple Handlers. This process could take longer than the 12s that AWS allows before returning an Error code.
Is there a way to return a response back to the caller to say that the event has been created while still contining with the process? That is to say fire off a separate task that performs the long running piece of code, that also catches and logs errors. Then return a value back to the user saying the Event has been successfully created?
I believe that ASP.NET spins up a new instance each time a call is made, will the old instance die one a value is returned, killing the task?
I could be wrong with a number of points here, this is my knowledge gleaned from the internet but I could have missunderstood articles.
Thanks.
Yes, you should pass the long-running task off to a background process and return to the user. When the task is complete, notifiy the user with whatever mechanism is appropriate for your site.
But do not start a new thread, what you want is to have a background service running for this, and use that to manage your request.
If a new thread is running the long operation it will remain “open/live” until it finishes. Also you can configure the app pool to always be active.
There are a lot of frameworks to work with long running tasks like Hangfire.
And to keep the user updated with the status of the task you can use SignalR to push notifications to the UI
I am developing a web-api that takes data from client, and saves it for later use. Now i have an external system that needs to know of all events, so i want to setup a notification component in my web-api.
What i do is, after data is saved, i execute a SendNotification(message) method in my new component. Meanwhile i don't want my client to wait or even know that we're sending notifications, so i want to return a 201 Created / 200 OK response as fast as possible to my clients.
Yes this is a fire-and-forget scenario. I want the notification component to handle all exception cases (if notification fails, the client of the api doesn't really care at all).
I have tried using async/await, but this does not work in the web-api, since when the request-thread terminates, the async operation does so aswell.
So i took a look at Task.Run().
My controller looks like so:
public IHttpActionResult PostData([FromBody] Data data) {
_dataService.saveData(data);
//This could fail, and retry strategy takes time.
Task.Run(() => _notificationHandler.SendNotification(new Message(data)));
return CreatedAtRoute<object>(...);
}
And the method in my NotificationHandler
public void SendNotification(Message message) {
//..send stuff to a notification server somewhere, syncronously.
}
I am relatively new in the C# world, and i don't know if there is a more elegant(or proper) way of doing this. Are there any pitfalls with using this method?
It really depends how long. Have you looked into the possibility of QueueBackgroundWorkItem as detailed here. If you want to implement a very fast fire and forget you also might want to consider a queue to pop these messages onto so you can return from the controller immediately. You'd then have to have something which polls the queue and sends out the notifications i.e. Scheduled Task, Windows service etc. IIRC, if IIS recycles during a task, the process is killed whereas with QueueBackgroundWorkItem there is a grace period for which ASP.Net will let the work item finish it's job.
I would take a look on Hangfire. It is fairly easy to setup, it should be able to run within your ASP.NET process and is easy to migrate to a standalone process in case your IIS load suddenly increases.
I experimented with Hangfire a while ago but in standalone mode. It has enough docs and easy to understand API.
We have a situation where we need to execute some long running code in the InitializeService method of a Data Service. Currently the first call to the data service fires off the code, but does not receive a response until the long running code has finished. The client is not required to wait for this action to complete. I have attempted to use a new thread to execute the code, however with the code being run we are replacing some files on the server which seems to kill the thread and causes it to bomb out. If I don't have it in a thread it runs fine, but the InitializeService method takes a long time to complete.
Are there any other ways to run this code asynchronously (was thinking maybe there is a way to call another method in the same fashion that a client would)?
Thanks in advance.
All WCF communication is basically Asynchronous. Each call spins up its own thread on the host and the processing starts. The problem you're running into, like many of us, is that the client times out before the host is finished with the work, and there's no easy way around that beyond setting the timeout to some ridiculous amount of time.
It's better to split your processing up into two or more parts, starting the intialization process and finishing the initialization process in separate steps, like this:
One option you could try a duplexed WCF service with a call back function to the client. In other words, client "A" calls the host and starts the initialization routine, but the host immediately sends back the client a value of IntializationStart=True so that the client isn't left waiting for the timeout. Then, when the host has finished compiling the files, it calls the client (which has its own listener) and sends a messages that the initialization is ready. Then the client calls the host and downloads the processed files.
This will works well PC-to-server, or server-to-server.
Another option could work this way: client "A" contacts host and host starts the Initialization routine, again sending back IntializationStarted=True. The host sets an internal (DB) value of FilesReady=False for client "A" until all the files are finished. At that point, host sets its internal value of FilesReady=True. Meanwhile, the client is on a timer, polling the host every minute until it finally receives that FilesReady=True, then it downloads the waiting files.
If you're talking about an iPhone-to-server or Android-to-server, then this is a better route.
You follow?
I am creating a Windows Service app that I would like to have programmatically pause when either a system error, odbc connection, or missing file error occur while . I was wondering if anyone knows how to do this? The Windows service app uses an odbc connection and datareader to connect to an MS Access database and an Oracle table, so there are the probable errors that I would be handling with those, I just want to allow a pause for the user handle the errors if/when they occur.
ServiceController service = new ServiceController(serviceName);
TimeSpan timeout = TimeSpan.FromMilliseconds(timeoutValue);
service.Pause(); //or whatever you want here.
sevice.WaitForStatus(ServiceControllerStatus.Paused, timeout);
...
Then to restart, do the same thing except for
service.Continue();
sevice.WaitForStatus(ServiceControllerStatus.Running, timeout);
You can do this for any state you want. Check out the msdn documentation by googling SeviceController. It will be the first result returned.
Also, you will need to handle the OnPause and OnContinue events in your service.
Have you tried?
System.Threading.Thread.Sleep(1000); // sleep for 1 second
Adjust the 1000 to 1000 times however long you want it to sleep in seconds.
Assuming that your service has a continual loop that checks for data, add a check to an external source for pause/continue commands. This source can be a message queue like MSMQ or a database table.
I implemented something along like this by having my service continually check a table for commands, and reporting its status in another table. When it gets a start command it launches a processing loop on another thread. A stop command causes it to signal the thread to gracefully exit. The service core never stops running.
The user interacts via a separate app with a UI that lets them view the service's status and submit commands. Since the app does its control via a database it doesn't have to run on the same machine that the service is running on.
I want to create a thread on user_login Event or Form_load Event.
In this thread i want to call a class function to execute some sql statement, and the user do not have to wait for the result or background process to be finished, he is just directed to his desired page let say my profile or what ever.
I am using ASP.NET, C#.
For what it is worth, this is a Bad Idea. There are a variety of ways that that IIS could terminate that background thread (IIS restart, app pool restart, etc., all of which are normal expected behavior of IIS), and the result would be that your DB transaction gets silently rolled back.
If these queries need to be reliably executed, you should either execute them in the request or send them to a windows service or other long-lived process. This doesn't mean that the user can't get feedback on the progress- the IIS request itself could be executed via an AJAX call.
Here are some examples of asynchronous calls in C#.
http://support.microsoft.com/kb/315582
The choice of pattern depends on your needs. Note that in sample 5 you can provide null as the callback if you don't want any code executed when the action is done.
You could do this by calling your method in a thread using Thread.Start. IsBackground is false by default, which should prevent your application from stopping.
http://msdn.microsoft.com/en-us/library/7a2f3ay4.aspx
But, since most of your time will probably be spent in your database call. Why not just execute it asynchronously without a callback? On a SqlCommand that would be BeginExecuteNonQuery.