.Net Session (режим StateServer) не синхронизируется при манипуляциях после завершения запроса - PullRequest
0 голосов
/ 06 июня 2018

Я немного разочарован этой проблемой:

У меня есть веб-сайт, который управляет некоторыми файлами для загрузки, потому что эти файлы очень большие, их нужно упорядочить в папки, а затем сжать.построить структуру 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;
        }
...