noetic
noetic

Reputation: 292

Long-running code within asp.net process

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.

Upvotes: 5

Views: 9673

Answers (9)

RickAndMSFT
RickAndMSFT

Reputation: 22780

  1. QueueBackgroundWorkItem My sample shows sending email.
  2. HangFire Open source project works on shared hosting.
  3. On Azure, you can use WebJobs.
  4. On Azure, Cloud services

Upvotes: 3

odinserj
odinserj

Reputation: 964

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.

Upvotes: 2

sigi
sigi

Reputation: 153

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

Upvotes: 0

Ash
Ash

Reputation: 62096

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>

Upvotes: 0

Eric Z Beard
Eric Z Beard

Reputation: 38406

This has been discussed as a part of other questions:

Multithreading in asp.net

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.

Upvotes: 5

mattlant
mattlant

Reputation: 15451

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.

Upvotes: 0

Mike
Mike

Reputation: 5281

Server.ScriptTimeout = 360000000;

Upvotes: -4

JPrescottSanders
JPrescottSanders

Reputation: 2151

I can think of two possible paths I'd head down:

  1. 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.
  2. 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.

Upvotes: 1

madcolor
madcolor

Reputation: 8170

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.

Upvotes: 0

Related Questions