WEB耗時任務的處理方案

最近有一個需求,從網頁上傳一個文本包到後臺處理,處理時長可能在幾分鐘到幾十分鐘。原來的方案就是直接接收一個ajax請求處理數據,然後返回。遇到的問題是:經過十幾分鐘的處理後,後臺返回結果到前端,前端收不到該結果了。我想應該是http連接超時了,除非長連接,沒有哪個請求可以這樣無限制地等待。於是着手改進方案,先說一下思路:

        1.前端上傳文件到後臺後,後臺開啓一個子線程處理耗時任務,主線程直接返回結果給前端,當前請求結束,無須等待子任務的處理結果。注意這裏的返回結果只是表示文件上傳成功,是一個階段性的結果而已。

        2.前端開啓一個輪詢,每隔一秒查一下當前任務的處理進度,直到任務處理結束。

        回答一下這個思路中的幾個關鍵點

        1.輪詢檢查的依據是什麼?後臺根據什麼來知道當前是誰在查詢?答案:Session.對Session不太瞭解的同學可以再做一下功課,這裏不展開。

        2.主線程和新開的子線程之間是需要交換數據的,包括子線程和查詢線程之間也是需要交換數據的,這個交換數據是用什麼來實現?答案:HttpRuntime Cache,對這個不熟悉的也做一下功課,這裏簡單理解爲就是一塊可以共享數據的內存區域。

        好了,思路和關鍵點都解決了,這裏再來貼一下關鍵點的代碼,讓大家有一個更清晰的認識

        1.開啓子線程       

//sessionid是作爲一個參數傳到子線程裏面去的,我們保存數據到cache中是以sessionid+關鍵字的形式來做key值,而session值是不能在子線程中直接獲取的,所以傳進去

String sessionId = Session.SessionID;

ThreadProc threadProc = new ThreadProc(sessionId);

Thread thread = new Thread(new ThreadStart(threadProc.process));

thread.IsBackground = true;

thread.Start();

          子線程類:         

class ThreadProc{

      private string sessionId = "";

      public ThreadProc(string sessionId){

             this.sessionId = sessionId;

      }

      public void process(){

             //這裏具體處理耗時任務

             //保存結果

             cache.WriteCache<Result>(result,sessionId+"result");

      }

} 

 

            2.cache的存取

            Cache cache = new Cache();

            //讀取

             Result result = cache.GetCache<Result>(sessionId+"result");

            //保存

            cache.WriteCache<Result>(result,sessionId+"result");

             這裏Cache類是對原始HttpRuntime Cache的一次封裝,示例如下             

public class Cache{

       private static System.Web.Caching.Cache cache = HttpRuntime.Cache;

       public T GetCache<T>(string cacheKey) where T:class{

               if(cache[cacheKey]  != null){

                       return (T)cache[cacheKey];

                }

                return default(T);

        }

        public void WriteCache<T>(T value,string cacheKey) where T:class{

                cache.Insert(cacheKey,value,null,DateTime.Now.AddMinute(10),System.Web.Caching.Cache.NoSlidingExpiration);

        }

}

                3.輪詢處理                   

public string CheckProcState(){

       string sessionId = Session.SessionID;

       Cache cache = new Cache();

       Result result = cache.GetCache<Result>(sessionId+"result");

       return result.ToJson();

}

 

            好啦,大體過程就是這樣了,歡迎大家指正,也歡迎討論其他處理長耗時任務的可具體實施的思路。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章