Правильно реализовать фоновый процесс Thread в ASP.NET

Мне нужно выполнить бесконечный цикл while и начать инициировать выполнение в global.asax. Мой вопрос: как именно я должен это делать? Должен ли я начать новую тему или использовать Async и Task или что-нибудь еще? Внутри цикла while мне нужно сделать await TaskEx.Delay(5000);

Как это сделать, чтобы он не блокировал другие процессы и не создавал утечки памяти?

Я использую VS10, AsyncCTP3, MVC4

EDIT:

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

Все, что мне нужно сделать, это запустить это как экземпляр singleton по всему миру, пока доступно приложение.

РЕДАКТИРОВАТЬ: решаемые

Это окончательное решение в 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
    {
            ///
    }
}

Я нашел эту приятную статью о том, как использовать async worker: http://www.dotnetfunda.com/articles/article613-background-processes-in-asp-net-web-applications.aspx

И это: http://code.msdn.microsoft.com/CSASPNETBackgroundWorker-dda8d7b6

Но я думаю, что для моих потребностей это будет идеально: http://forums.asp.net/t/1433665.aspx/1

Ответ 2

ASP.NET не предназначен для обработки такого требования. Если вам нужно что-то запускать постоянно, вам лучше создать службу Windows.

Update

ASP.NET не предназначен для длительных задач. Он предназначен для быстрого реагирования на HTTP-запросы. См. Ответ Cyborgx37 или Могу ли я использовать потоки для выполнения длительных заданий в IIS? по нескольким причинам почему.

Update

Теперь, когда вы, наконец, упоминали, что работаете с SignalR, я вижу, что вы пытаетесь разместить SignalR в ASP.NET, правильно? Я думаю, вы ошибетесь, см. Пример пакет NuGet, на который ссылается вики проекта. В этом примере для управления задачами используется IAsyncHttpHandler.

Ответ 3

Вы можете запустить поток в своем global.asax, однако он будет работать только до тех пор, пока процесс asp.net не будет переработан. Это произойдет не реже одного раза в день, или когда никто не использует ваш сайт. Если процесс перерабатывается, единственный способ перезапустить поток - это когда у вас есть хит на вашем сайте. Таким образом, поток не работает непрерывно.

Чтобы продолжить процесс, лучше запустить службу Windows.

Если вы выполняете "In process" решение, это зависит от того, что вы делаете. Сама нить не вызовет никаких проблем с памятью или взаимоблокировками. Вы должны добавить меганизм, чтобы остановить поток, когда приложение остановится. В противном случае перезапуск займет много времени, потому что он будет ждать остановки вашего потока.

Ответ 4

Это зависит от того, что вы пытаетесь выполнить в своем цикле while, но в целом это такая ситуация, когда Служба Windows является лучший ответ. Установка службы Windows потребует наличия у вас прав администратора на веб-сервере.

С бесконечным циклом вы получаете множество проблем, связанных с насосом сообщений Windows. Это то, что поддерживает приложение Windows, даже когда приложение ничего не делает. Без него программа просто заканчивается.

Проблема с бесконечным циклом заключается в том, что приложение застряло "что-то", что мешает другим приложениям (или потокам) "делать" свою вещь. Было несколько обходных решений, таких как DoEvents в Windows Forms, но все они имеют некоторые серьезные недостатки, когда дело доходит до отклика и управления ресурсами. (Допустимо для небольшого приложения LOB, возможно, не на веб-сервере.) Даже если цикл while находится в отдельном потоке, он будет использовать всю доступную вычислительную мощность.

Асинхронное программирование действительно больше предназначено для длительных процессов, таких как ожидание возврата базы данных или ожидание выхода принтера в онлайн-режиме. В этих случаях это внешний процесс, который занимает много времени, а не цикл while.

Если служба окон недоступна, я думаю, что ваш лучший выбор - это настроить отдельный поток с помощью своего собственного насоса сообщений, но это немного сложно. Я никогда не делал этого на веб-сервере, но вы могли бы запустить приложение. Это обеспечит вам сообщение и позволит вам реагировать на события Windows и т.д. Единственная проблема заключается в том, что это приведет к запуску приложения Windows (либо WPF или WinForms), что может быть нежелательно на веб-сервере.

Чего вы пытаетесь достичь? Есть ли другой способ, которым вы можете это сделать?