19

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

Volodymyr
  • 1,209
  • 1
  • 15
  • 26
Registered User
  • 3,669
  • 11
  • 41
  • 65
  • 1
    What does Clients.SetConnectionTimeStamp do? What is the purpose of it? What specific functionality are you looking to implement? If you want a quality answer, you need to provide this information. – cadrell0 Jun 01 '12 at 15:18
  • This is better to do it with a timer. – Aristos Jun 01 '12 at 15:19
  • @cadrell0 I want to Broadcasting over a Hub from outside of a Hub https://github.com/SignalR/SignalR/wiki/Hubs – Registered User Jun 01 '12 at 15:20
  • 3
    If you were able to answer your own question, please post it as an answer and mark it as accepted. – cadrell0 Jun 01 '12 at 16:54

5 Answers5

15

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.

Community
  • 1
  • 1
jrummell
  • 42,637
  • 17
  • 112
  • 171
  • 2
    The first link doesn't provide any reasons why at all, the second link only states the very obvious concern that the server might choose to recycle the app pool at some point. I've yet to hear a valid concern why this is a "bad idea". To factor something out into a windows service, making your application much more difficult to deploy, sounds like the bad idea to me. Does somebody has a real reason or is this merely ideology? – John Sep 14 '14 at 17:39
  • _... very obvious concern that the server might choose to recycle the app pool at some point_ That's a pretty big deal... – jrummell Sep 15 '14 at 18:09
  • 2
    All applications go down at some point, that's not unique to ASP.NET. Are you arguing against doing background jobs in WinForms applications because the user can click the close button at any time? Even Windows Services need to go down when the server is restarted. How is this different? – John Sep 15 '14 at 18:24
  • 3
    I'm not arguing at all, just stating my opinion :). I don't think that's necessarily a parallel comparison because in both Forms and Services, a user action is shutting down the application while the IIS Application Pool could be recycled for multiple reasons outside the user's control (lifetime, request count, memory usage, etc). – jrummell Sep 15 '14 at 18:31
10

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.

Peter
  • 27,590
  • 8
  • 64
  • 84
  • 1
    Excellent! I have no problems them getting recycled. That is one of the requirements. – Registered User Jun 01 '12 at 14:56
  • I agree with peer. The solution and a warning to the dangers of this can be found in this great article: http://haacked.com/archive/2011/10/16/the-dangers-of-implementing-recurring-background-tasks-in-asp-net.aspx/ – Ricardo C Oct 16 '14 at 19:52
5

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

NeVeS
  • 48
  • 1
  • 5
MarianoC
  • 341
  • 3
  • 3
2

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?

JDB
  • 25,172
  • 5
  • 72
  • 123
1

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

Registered User
  • 3,669
  • 11
  • 41
  • 65
  • Careful - the infinite loop will chew up your processor. Also, you'll have to make sure you don't accidentally start multiple instances of these things (which implies some multi-threading checks). – JDB Jun 01 '12 at 16:14
  • @Cyborgx37 Well, this is why I have posted the OP, but unfortunately on SO there is too much noise... Also if you had read the OP yourself you would have known that the thread will be put to a long sleep so there is no CPU issue there. – Registered User Jun 01 '12 at 16:21