E.g. we this code in the asp.net form codebihind:
private void btnSendEmails_OnClick()
{
Send100000EmailsAndWaitForReplies();
}
This code execution will be killed by the timeout reason.
For resolving the problem I’d like to see something like this:
private void btnSendEmails_OnClick()
{
var taskId = AsyncTask.Run( () => Send100000EmailsAndWaitForReplies() );
// Store taskId for future task execution status checking.
}
And this method will be executed for some way outside the w3wp.exe process within a special enveronment.
Does anybody know a framework/toolset for resolving this kind of issues?
Update: The emails sending method is only an example of what I mean. In fact, I could have a lot of functionality need to be executed outside the asp.net working process.
E.g. this point is very important for an application which aggregates data from a couple of 3rd party services, do something with it and send it back to another service.
Answers:
Thank you for visiting the Q&A section on Magenaut. Please note that all the answers may not help you solve the issue immediately. So please treat them as advisements. If you found the post helpful (or not), leave a comment & I’ll get back to you as soon as possible.
Method 1
This has been discussed as a part of other questions:
BackgroundWorker thread in ASP.NET
There is no good way to do this. You don’t want any long running processes in the ASP.NET worker process, since it might recycle before you are done.
Write a Windows Service to run in the background that does the work for you. Drop messages into MSMQ to initiate tasks. Then they can run as long as they want.
Method 2
- QueueBackgroundWorkItem My sample shows sending email.
- HangFire Open source project works on shared hosting.
- On Azure, you can use WebJobs.
- On Azure, Cloud services
Method 3
I can think of two possible paths I’d head down:
- You could create a windows service that hosted a remoted object and have your web app call that remoted object to ensure that the method executed outside of the IIS process space.
- You could set up a DB or MSMQ to which you would log a request. Your web app could then monitor the status of the request to subsequently notify the user of it’s completion. I would envision a service completeing the requests.
Method 4
ASP.NET hosting environment is very dangerous for any long-running processes, either CPU or I/O consuming, because sudden AppDomain unloads may happen.
If you want to perform background tasks outside of request processing pipeline, consider using http://hangfire.io, it handles all difficulties and risks of background processing for you, without the requirement to install additional windows service (but it is possible to use them, when the time come). There is a mail sending tutorial either.
Method 5
One option is to have the task execute a certain amount of emails, then Response.Redirect back to itself and repeat until all of your emails have been sent.
Method 6
You could have the functionality that sends the mails run as a service. Submit the request to it, and let it process it. Query every once in a while for its status. If you have control of the server you can install a windows service which would probably be ideal for optimal processing and lifetime management.
Method 7
ASP.NET 2.0+ supports the concept of Asynchronous pages. Add the page directive Async=”true” to your page.
Then in Page_Load, use the BeginEventHandler and EndEventHandler delegates to have code executed asynchronously in the corresponding “handlers”.
<%@ Page Language="C#" Async="true" %>
<script runat="server">
protected void Page_Load(object sender, EventArgs e)
{
BeginEventHandler begin = new BeginEventHandler(BeginMethod);
EndEventHandler end = new EndEventHandler(EndMethod);
AddOnPreRenderCompleteAsync(begin, end);
}
</script>
Method 8
It can be often impossible to run a custom windows service when your site is hosted by a shared hosting provider. Running a separate thread that you put to sleep to run in regular intervals can be inconsistent since IIS will tend to recycle your threads every now and then, and even setting the script-execution property in cofig file or through code will not enshure that your thread doesnt get killed off and recycled.
I came accross a cache expiration based method, which given the methods available on a shared hosting service might be the safest, i.e. most consistent option to go for. This article explains it quite well and provides a job-queue class to help manage your scheduled jobs at the end of the article, see it here – http://www.codeproject.com/KB/aspnet/ASPNETService.aspx
Method 9
Server.ScriptTimeout = 360000000;
All methods was sourced from stackoverflow.com or stackexchange.com, is licensed under cc by-sa 2.5, cc by-sa 3.0 and cc by-sa 4.0