Меня немного расстраивает эта проблема:
У меня есть веб-сайт, который управляет некоторыми файлами для загрузки, потому что эти файлы очень большие и должны быть организованы в папки, а затем уплотнены, я создаю структуру Ajax, которая выполняет эту работу в фоновом режиме, и когда эти файлы будут готовы к загрузке , это задание изменяет статус объекта в пользовательском сеансе (bool isReady = true, просто вот так).
Чтобы достичь этого, когда пользователь нажимает кнопку «загрузить», сообщение jquery отправляется в API, и этот API запускает задание «организатор» и завершает код (основной поток, область действия запроса), оставляя фоновый поток, выполняющий магия (это так красиво, ха-ха).
Это «организаторское» задание является фоновым потоком, который получает HttpSessionState (HttpContext.Current.Session) параметром. Он упорядочивает и архивирует файлы, создает ссылку для загрузки и, в конце концов, изменяет объект в сеансе с помощью HttpSessionState, полученного параметром param.
Это отлично работает, когда я использую сеансовый режим «InProc» (я был очень рад развернуть этот мир искусства в продакшене после тестов).
Но мои кошмары начались, когда я развернул проект в производственной среде, потому что мы используем режим «StateServer» в этой среде. В этих условиях изменения не применяются.
До сих пор я замечал, что в StateServer каждое изменение, которое я делаю в фоновом потоке, не «фиксируется» для сеанса, когда изменения происходят ПОСЛЕ завершения пользовательского запроса (поток, запускающий поток). Если я напишу thread.join (), чтобы дождаться завершения потока, применяются изменения, сделанные внутри потока.
Я думаю об использовании БД для хранения этих значений, но я потеряю некоторую производительность :(
[HttpPost]
[Route("startDownloadNow")]
public void StartDownloadNow(DownloadStatusProxy input)
{
//some pieces of code...
...
//add the download request in the user session
Downloads.Add(data);
//pass the session as parameter to the thread
//cause the thread itself don't know the current httpcontext session
HttpSessionState session = HttpContext.Current.Session;
Thread thread = new Thread(() => ProccessDownload(data, session));
thread.Start();
//here, if I put a thread.join(), the changes inside the thread are applied correctly, but I can't do this, otherwise, it ceases to be ajax
}
private void ProccessDownload(DownloadStatus currentDownload, HttpSessionState session)
{
List<DownloadStatus> listDownload = ((List<DownloadStatus>)session["Downloads"]);
try
{
//just make the magic...
string downloadUrl = CartClient.CartDownloadNow(currentDownload.idRegion, currentDownload.idUser, currentDownload.idLanguage, currentDownload.listCartAsset.ToArray(), currentDownload.listCartAssetThumb.ToArray());
listDownload.Find(d => d.hashId == currentDownload.hashId).downloadUrl = downloadUrl;
listDownload.Find(d => d.hashId == currentDownload.hashId).isReady = true;
//in this point, if I inspect the current session, the values are applied but, in the next user request, these values are in the previous state... sad... .net bad dog...
}
catch (Exception e)
{
listDownload.Find(d => d.hashId == currentDownload.hashId).msgError = Utils.GetAllErrors(e);
LogService.Log(e);
}
//this was a desesperated try, I retrieve the object, manipulated and put it back again to the session, but it doesn't works too...
session["Downloads"] = listDownload;
}
Я думаю, что StateServer быстрее, чем хранить данные в БД, потому что сеанс работает в памяти, а БД использует ввод-вывод. Я ошибся? Или этот спектакль не такой большой, что я должен его учитывать?





Если вы уже используете «StateServer», то я не понимаю, почему фраза «Я подумываю об использовании БД для хранения этих значений, но я потеряю некоторую производительность» вообще имеет смысл. Что такое StateServer, если это не база данных? Если бы это был я, я бы отказался от любой концепции состояния сеанса на веб-сервере. Это сломанная концепция, которая не масштабируется. Храните все в базе данных (без адаптера для сохранения состояния сеанса).