Registered User
Registered User

Reputation: 3699

Correctly implement background process Thread in ASP.NET

I need to execute an infinite while loop and want to initiate the execution in global.asax. My question is how exactly should I do it? Should I start a new Thread or should I use Async and Task or anything else? Inside the while loop I need to do await TaskEx.Delay(5000);

How do I do this so it will not block any other processes and will not create memory leaks?

I use VS10,AsyncCTP3,MVC4

EDIT:

 public void SignalRConnectionRecovery()
        {
            while (true)
            {
                Clients.SetConnectionTimeStamp(DateTime.UtcNow.ToString());
                await TaskEx.Delay(5000);
            }
        }

All I need to do is to run this as a singleton instance globally as long as application is available.

EDIT:SOLVED

This is the final solution in Global.asax

protected void Application_Start()
{
    Thread signalRConnectionRecovery = new Thread(SignalRConnectionRecovery);
    signalRConnectionRecovery.IsBackground = true;
    signalRConnectionRecovery.Start();

    Application["SignalRConnectionRecovery"] = signalRConnectionRecovery;
}


protected void Application_End()
{
    try
    {
        Thread signalRConnectionRecovery = (Thread)Application["SignalRConnectionRecovery"];
        if (signalRConnectionRecovery != null && signalRConnectionRecovery.IsAlive)
        {
            signalRConnectionRecovery.Abort();
        }
    }
    catch
    {
            ///
    }
}

I found this nice article about how to use async worker: http://www.dotnetfunda.com/articles/article613-background-processes-in-asp-net-web-applications.aspx

And this: http://code.msdn.microsoft.com/CSASPNETBackgroundWorker-dda8d7b6

But I think for my needs this one will be perfect: http://forums.asp.net/t/1433665.aspx/1

Upvotes: 19

Views: 39086

Answers (5)

MarianoC
MarianoC

Reputation: 351

This is an old post, but as I was seraching for this, I would like to report that in .NET 4.5.2 there is a native way to do it with QueueBackgroundWorkItem.

Take a look at this post: https://blogs.msdn.microsoft.com/webdev/2014/06/04/queuebackgroundworkitem-to-reliably-schedule-and-run-background-processes-in-asp-net/

MarianoC

Upvotes: 5

Registered User
Registered User

Reputation: 3699

I found this nice article about how to use async worker, will give it a try. http://www.dotnetfunda.com/articles/article613-background-processes-in-asp-net-web-applications.aspx

And this: http://code.msdn.microsoft.com/CSASPNETBackgroundWorker-dda8d7b6

But I think for my needs this one will be perfect: http://forums.asp.net/t/1433665.aspx/1

Upvotes: 1

jrummell
jrummell

Reputation: 43087

ASP.NET is not designed to handle this kind of requirement. If you need something to run constantly, you would be better off creating a windows service.

Update

ASP.NET is not designed for long running tasks. It's designed to respond quickly to HTTP requests. See Cyborgx37's answer or Can I use threads to carry out long-running jobs on IIS? for a few reasons why.

Update

Now that you finally mentioned you are working with SignalR, I see that you are trying to host SignalR within ASP.NET, correct? I think you're going about this the wrong way, see the example NuGet package referenced on the project wiki. This example uses an IAsyncHttpHandler to manage tasks.

Upvotes: 15

Peter
Peter

Reputation: 27944

You can start a thread in your global.asax, however it will only run till your asp.net process get recycled. This will happen at least once a day, or when no one uses of your site. If the process get recycled, the only way the thread is restarted agian, is when you have a hit on your site. So the thread is not running continueuosly.

To get a continues process it is better to start a windows service.

If you do the 'In process' solution, it realy depends on what your are doing. The Thread itself will not cause you any problems in memory or deadlocks. You should add a meganism to stop your thread when the application stops. Otherwise restarting will take a long time, because it will wait for your thread to stop.

Upvotes: 10

JDB
JDB

Reputation: 25810

It depends what you are trying to accomplish in your while loop, but in general this is the kind of situation where a Windows Service is the best answer. Installing a Windows Service is going to require that you have admin privileges on the web server.

With an infinite loop you end up with a lot of issues regard the Windows message pump. This is the thing that keeps a Windows application alive even when the application isn't "doing" anything. Without it, a program simply ends.

The problem with an infinite loop is that the application is stuck "doing" something, which prevents other applications (or threads) from "doing" their thing. There have been a few workarounds, such as the DoEvents in Windows Forms, but they all have some serious drawbacks when it comes to responsiveness and resource management. (Acceptable on a small LOB application, maybe not on a web server.) Even if the while-loop is on a separate thread, it will use up all available processing power.

Asynchronus programming is really designed more for long-running processes, such as waiting for a database to return a result or waiting for a printer to come online. In these cases, it's the external process that is taking a long time, not a while-loop.

If a Window Service is not possible, then I think your best bet is going to be setting up a separate thread with its own message pump, but it's a bit complicated. I've never done it on a web server, but you might be able to start an Application. This will provide a message pump for you and allow you to respond to Windows events, etc. The only problem is that this is going to start a Windows application (either WPF or WinForms), which may not be desirable on a web server.

What are you trying to accomplish? Is there another way you might go about it?

Upvotes: 2

Related Questions