Я немного разочарован этой проблемой:
У меня есть веб-сайт, который управляет некоторыми файлами для загрузки, потому что эти файлы очень большие, их нужно упорядочить в папки, а затем сжать.построить структуру Ajax, которая выполняет эту работу в фоновом режиме, и когда эти файлы готовы к загрузке, это задание изменяет состояние объекта в пользовательской сессии (bool isReady = true, просто так).
Для достижения этого, когда пользователь нажимает «загрузить», сообщение jquery отправляется в API, и этот API запускает задание «организатор» и завершает код (основной поток, один из запросов), оставляя фоновый поток, выполняющиймагия (это так прекрасно, ха-ха).
Это "организаторское" задание является фоновым потоком, который получает HttpSessionState (HttpContext.Current.Session) по параметру.Он организует и архивирует файлы, создает ссылку для загрузки и, в конце, изменяет объект в сеансе, используя HttpSessionState, полученный параметром.
Это прекрасно работает, когда я использую сеанс "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;
}