I have a website application and one page allows the user to update the database in a way that could potentially take several minutes.
In the interest of avoiding time outs and keeping the site responsive, how can I run a lengthy task like this?
I found the article Background tasks with hosted services in ASP.NET Core, but it' talking about timers and stuff and I don't see how that would apply to my case.
Can anyone point me to a modern example that shows how to run a lengthy from a web request?
Note that it would be nice to be able to tell the user when the task is complete, but that may not be totally necessary.
Also note, the actually work will be done by calling a RESTful API. So providing progress updates via AJAX is not an option.
For this kind of function what I do will like below
Call update database API and the API will run update script asynchronized.
Before run update script asynchronized, insert a status record to database, redis or file which you prefer for record updating task status.
The API return processing status to front-end
After updating task change the status to success
Before the status is success, we show a loading for user
You can send a notify to user after task success
Related
I have an excel sheet that contains 50,000 rows, Now I have to update these using EF.
but Without full-cycle complete, I can't send any success message to the user, and the web page shows "Processing....." and every other operation is stopped, when the operation is done after 10-15 min later, then the user can see the success message.
Now I want to do: User can see progress, such as "1000/ 50000 data updated", "2000/ 50000 data updated", "50000/ 50000 data updated". and user can do other operation between the current operation.
I tried using Async, But I can't find out the exact result.
Technology:
Asp.Net Core MVC 3.1
EF Core 3.1
SQL server 2017
The async and await keywords don't cause additional threads to be created.
So, It means if you want a job run in the background separately, you should use Threads nor async. foo more explanation about the difference of thread and async you can follow this Eric Lippert's answer.
But fortunately, there are exist some library that you can use for handling Background workers, such as Hangfire. They define themself as below:
An easy way to perform background processing in .NET and .NET Core applications. No Windows Service or separate process required. Backed by persistent storage. Open and free for commercial use.
and you said you want to display a progress bar to the user, that you can handle tracking progress by hangfire too.
good luck.
Based on yoour description and scenario, if possible, you can try following approach to achieve it:
1) For long-running bulk update operation, you can create and use a background task to handle it.
For exampel, using a queue triggered task, user can create a queue message for each new bulk update operation, then task would be triggered and process data from excel file.
2) For displaying progress of bulk update operation to web client user, you can integrate ASP.NET Core SignalR real-time web functionality into web client application.
In background task, call hub method to push progress message to the connected SignalR web client user(s).
I realise this question has been asked in different variations but with newer features to .net (e.g. async await) I wonder what solution is the best.
I have a C# .Net Web Forms app that has a long running task: The task handles a user request where they upload a csv data file, serialises into object, and imports to a database. The task can take a few minutes and the browser regularly times out - this causes usability issues.
I have seen many solutions whereas the user will upload the data and then the task is carried out in the background. The page will then call the server intermittently to request the status of the task, thus keeping the user informed of the progress.
I would like to know how this is achieved? The options I see on the table:
Windows Service
Web Service - how is this hosted: IIS or a windows service?
Async, Await - is this a possibility?
I think you could take two different approaches.
The first would be a pull approach, you would be keeping the state of the process per user in the server, perhaps in session, and having the process update that state, then the client can pull the actual state via ajax regularly. The ajax call is made from the client's browser, and the function can be put in the same web page that the client is viewing, there's no need to separate it if it's going to be used only from there.
The second could be a push approach, which is a bit more complex but gives you other possibilities. You would need to use a library like signalr https://www.asp.net/signalr, that allows you to communicate from the server to the client's browser, call JS functions, and push the updated state to the client's form. That could create a more functional two-way communication and a better user experience in exchange of a bit more complexity.
Once a day, I want my ASP.NET MVC4 website, which may be running on multiple servers, to email a report to me. This seems like a pretty common thing to want to do, but I'm having a tough time coming up with a good way to do it.
Trying to run a timer on a server to do this work is problematic for a couple of reasons. If I have multiple servers then I'd have the timer running on all of them (in case a server goes down); I'd need to coordinate between them, which gets complicated. Also, trying to access the database via Entity Framework from a background thread adds the complication that I must employ a locking strategy to serialize construction/disposal of the DbContext object between the periodic background thread and the "foreground" Controller thread.
Another option would be to run a timer on the servers, but to have the timer thread perform a GET to a magic page that generates and emails the report. This solves the DbContext problem because the database accesses happen in a normal Controller action, serialized with all of the other Controller accesses to the database. But I'm still stuck with the problem of having potentially more than one timer running, so I'd need some smarts in the Controller action to ignore redundant report requests.
Any suggestions? How is this sort of thing normally done?
You should not be doing this task from your web application as Phil Haack nicely explains it in his blog post.
How is this sort of thing normally done?
You could perform this task from a Windows Service or even a console application that is scheduled to run at regular intervals using the Windows Scheduler.
The proper solution is to create a background service that runs independently of your website. However, if that is not an option there is a hack where you can use the cache as explained in Easy Background Tasks in ASP.NET by Jeff Atwood.
A few options:
If you are hosting on Azure as a Website, check out WebJobs which was released recently in preview (http://azure.microsoft.com/en-us/documentation/articles/web-sites-create-web-jobs/)
If you don't want the pain of extracting out your email logic outside of the website, expose that functionality at a url (with a handler, mvc action, etc.) and then run a Windows Scheduled task that hits that url on a schedule.
Write a simple console app that is executed similarly via a Windows Scheduled task.
Or write a simple Windows Service that internally is looping and checking the time and when reached, hits that url, runs that exe, or has it's own code to send you the email.
I would recommend running Quartz.NET as a Windows Service:
Quartz.NET - Enterprise Job Scheduler for .NET Platform
There's boilerplate code for a Windows Service in the download.
We have a data transfer between 2 systems that can take upto a few hours. The code for doing this transfer is written in C#.
We would like to trigger the transfer with a WCF web service call.
Ideally we would like the web service call to return at once, with a message "OK job started", and then the job to run on the server untill it is complete.
What is the best way to do this?
The possible problems we see are:
web service timing out before job finished
job stops after returning result
Although not entirely similar to your predicament, I had a similar scenario with my MVC application. There are lots of "Jobs" to do that involve importing data, batch emails, financial processes etc.
Basically, I created a windows service which had a job manager, and obviously the various jobs that could be done. It also ran a light HttpServer. This allowed the main MVC application to talk to the service. One sends a request to start jobs and get the status of all jobs or a particular job (when a job is started it is given a unique ID).
So if I was going to implement it in your case, I'd add a download job which did the actual work, and instigate it from the MVC App via a JSON call. The status of the download could be queried at any time by using the ID passed back from the "StartJob" JSON call. Your main web request is therefore handled and over immediately.
I'd write a console application that does this job and let the Web Service call that application.
Running heavy processes within the web server itself is never a good idea.
You may use background thread on the WebServce call.
What if I have website with a button. User clicks on the button and starts a long running process. After a few hours (or minutes) user update webpage and see results. What is the best (and any other) way to implement long running operation on website?
From the user experience point of view I suggest you implement the job like you would implement order handling in an online shop.
When the user starts the job he should be able to track the state of the job. Is the job complete? Did the job fail? What is the progress of the job? He should probably also be able to cancel the job and perhaps modify properties of the job. You could implement an notification mechanism using e-mail or an SMS and the user should be able to control that.
By using JavaScript/AJAX you can provide a more interactive user experience where the job status web page is automatically refreshed at regular intervals in the background without forcing the user to refresh his browser.
The user should be able to leave his computer and later connect to the website from another computer and still be able to get information about pending and completed jobs. This requires some form of user login.
I suggest that you separate the job handling code from the website code. You could expose the job handling user a web service or another similar technology. The website should query the service and display the results providing a user interface on top of the job service.
How long? If it's really going to take hours, you don't want that code running in the web server. Have the server spawn an external process or start a service or something along that line, and put the long running code in there.
You could have that code put status updates somewhere (like in the database) as it runs, and the website can check that when the user comes back to see how it's doing.
I suggest you read up on Threading in asp.Net. For website performance, time consuming processes can be put on a different thread.
A different approach is executing the task with AJAX. This way, you can present the user interface to the user, and start an asynchronous process which handles the request.