task.factory startnew использование делает мой сайт время от времени пользователями - PullRequest
2 голосов
/ 20 октября 2011

Это порядок моего кода:

Я делаю несколько

task.factory.startnew(()=> myFunction(myObject, httpSessionState))

Я отправляю System.Web.SessionState.HttpSessionState в myFunction, потому что я не жду окончания задач, поэтому они запускаютсяв фоновом режиме, и я не могу получить сессию внутри myFunction, потому что

 System.Web.HttpContext.Current = null.

myFunction вызывает веб-сервисы и сохраняет их результат в httpSessionState объекте

, затем я делаю несколько вызовов ajax, чтобы получитьзначения сеанса с сервера, пока у меня не появятся все нужные значения.

ПРОБЛЕМА :

Я не могу объяснить, почему время от времени пользователи отключаются.Я предполагаю, что сессия становится нулевой.Все пользователи одновременно удаляются.Все объекты сеанса, вероятно, становятся нулевыми

Ответы [ 2 ]

2 голосов
/ 09 ноября 2011

Это, вероятно, происходит из-за необработанного исключения в ваших асинхронных Task (s), которое по умолчанию (начиная с .NET 2.0) завершает процесс, которому принадлежитнеисправный поток.

Процесс в ASP.NET, являющийся вашим рабочим процессом IIS.Когда рабочий процесс завершается, он убивает все текущие пользовательские сеансы, лишает законной силы любую аутентификацию, которую они имели с запущенным веб-приложением, и вынуждает их снова войти в систему.

Поскольку вы не ожидаете завершения запущенной задачи(Task.Wait() или Task<T>.Result), и, предположительно, не перехватывая и не обрабатывая исключения в Задачах, .NET выполняет свою операцию по умолчанию с необработанными исключениями, которая завершает процесс.

Есть хороший краткий обзор того, как это изменилось с .NET 1.1 на .NET 2.0+, а также некоторые опции для обработки ошибок здесь , а также другие методы обработки ошибок TPL здесь .


Исправление прерываний процесса зависит от ваших требований.

Подождите .Самым безопасным подходом было бы дождаться выполнения всех задач: Task.WaitAll(t1, t2, ...).Вы можете запускать их все параллельно, так что время ожидания будет равно длине самой длинной задачи, таким образом используя параллелизм для некоторого ускорения.

Если вы просто не можете ждать и действительно хотите позволить им сбежатьна заднем плане вам нужна защита:

Ласточка .Оберните тело действия / функции задачи в try-catch и выполните вход в улов, но «проглотите» исключение, а не перебрасывайте его.Это грязно, потому что вы в основном игнорируете ошибки в вашем приложении и могут привести к проблемам в нисходящем направлении, когда вы предполагаете, что задача выполнена успешно.

Продолжить игнорировать .По сути, это то же самое, что и проглатывание исключения: преимущество флага Task.Status устанавливается в Faulted вместо ошибочной рекламы RanToCompletion.Если вы настроили какой-либо механизм отслеживания задач, это может быть полезно при восстановлении или, по крайней мере, если вы предполагаете, что все прошло нормально (подробнее о продолжениях ошибок в первой ссылке выше).

Task.Factory.StartNew(() => myFunction(myObject, httpSessionState))
    .ContinueWith(faultedTask => 
    { 
        var ex = faultedTask.Exception; // reading the exception will ensure the process won't terminate
        Log.Error("Task Xyz failed", ex);
    },
    TaskContinuationOptions.OnlyOnFaulted |
    TaskContinuationOptions.ExecuteSynchronously);

справиться с этим .Вы должны настроить какой-либо способ отслеживания сбойных задач, восстановления после сбоев или повторного выполнения задач.Если вы можете зафиксировать успех / неудачу асинхронной задачи, ваш ajax-клиент, по крайней мере, может быть снабжен информацией для следующего разумного шага.Возможно, вы могли бы использовать какое-то состояние (страница, сеанс, база данных) для хранения и поиска состояния задачи по тому же ключу, который вы использовали для сохранения результатов задачи в сеансе.Затем перейдите к сеансу, чтобы получить результаты, основанные на статусе RanToCompletion;подождите или восстановите в противном случае.

2 голосов
/ 20 октября 2011

Обычно это происходит (потеря сеансов), когда сервер обрабатывает w3wp.exe перезапускается (пул приложений Asp.net).

Обычно хостинг-провайдеры имеют верхний предел памяти на пул приложений, который при достижении перезапускает пул, чтобы избежать перегрузки сервера.

Таким образом, в принципе это может означать, что ваше приложение потребляет много памяти (или имеет утечки памяти).

В вашей ситуации это может означать, что возникающие у вас задачи слишком тяжелые или текущие, что указывает на необходимость проверки myFunction ().

Если вам нужно ограничить степень параллелизма для точной настройки использования памяти: http://msdn.microsoft.com/en-us/library/ee789351.aspx

...