mvc ActionResult & ajax post & Session 合在一起就出現 奇怪問題....
這次是寫 "處理進度表" 遇到個奇怪問題
又是找了老半天 終於找到了
有個server 後端程式 需處理大量資料
雖然 可以 在前端 跑出 處理中.....
但是真的很久......
所以 "處理進度表" 是無法避免的 解決方案
我的解決方式是:
用 setInterval("Ckconnect()", 1000);
啟動一個 ajax
function Ckconnect() {
$.post("/Main/Ajax_DT", {})
.done(function (Rdata) {
var dta = Rdata.DT_STR.split('-');// replace('-',",");
var time = dta[0] + "/" + dta[1] + "/" + dta[2] + " " + dta[3] + ":" + dta[4] + ":" + dta[5];
$("#ckdt").text(time + ":" + Rdata.proValue);
$('#WaitP').progressbar('setValue', Rdata.proValue);
});
}
1秒去看一下 Rdata.proValue 處理進度值
而處理的話 也是 post 一個 資料回後端
$.post("/Main/Ajax_Wdata", {....})
後端就
while(...)
{
變更 Rdata.proValue; 值 讓前台知道
}
******************************************
一開始測都正常 ....
整個專案就在今天寫完測試時
突然發現 進度值 不動了 測試時間也不動了
確定是 "/Main/Ajax_DT" 沒回應
等 "/Main/Ajax_Wdata" 處理完後 時間才動
怎麼會變這樣....
***********************
用新的專案測試後
一個是隔 1秒用 $.post("/Main/Ajax_DT", {}) 去server 要時間
一個是故意 卡死一個 後端
public ActionResult Begin_Test()//卡死測試
{
while (true)
{
Pub_param.proValue++;
Thread.Sleep(1000);
if (Pub_param.Max_data == 100)
break;
}
return Json("OK");
}
但要小心 畢竟一些資料是存在 user端 容易被竄改 有時還會被擋
所以如不是非要用到 需要 2個 ajax 同時回應訊息且cookie資料不重要我才用
一般非必要我覺得我還是會用 Session
畢竟是安全 好處理 ,不用擔心用戶端封鎖cookie
記憶體問題? 能用錢解決的問題就不是問題
用戶同時連線都多到讓server 負擔不了的這種程度...還擔心錢?
+CPU+RAM+SSD ....這都比 資料安全性問題 簡單太多了
而且操作時點一下等一下(不要太久)是還好...
不用Session 不用 Cookies
但是還是要暫存資料做 Action之間 傳遞資料
我是想到一方法解決..
自己利用 session ID 做標記
寫一套 類似存放server端的cookie 來解決 傳遞問題
工程有點浩大還要做測試驗證
真碰到有需要再說
***************************************
另一種解決方案
是看到
這是另一種問題 我也沒碰過
有人實做過
因為它是將 運行部分 丟到另一個執行緒去做 不占用web server
但還是要等他回來
所以他分2部分
還是等 我的執行程式Async 跑完 才會從 Completed return 回來
所以沒有解決這卡住問題
******************************
但這啟發我另一個想法 當還沒找到是Session 卡住時
就是 收到 Ajax 資料就丟給另一個 執行緒 跑,然後return 回來
射後不理..
讓另一個 Ajax 間隔1秒去 check 執行狀況
反正前方用 進度表擋住所有操作 等 執行緒通知 結束
再下一步就可以
這我有實做過類似的功能 但倒不是為了解決這問題
是為了解決 管控 多人同時處理資料庫 的問題用.
最後沒實作 是因 沒找到原因 心理總是毛毛的
畢竟應該是可以的 怎麼就突然卡死?
找不到 會不會 其他地方 死得更慘?
還好有找到
**********************
最後還是用了各人暫存表 來取代 session
使用方式
不能用 Session.SessionID;
Session.SessionID 要一致
就得啟用 Session
Session["id"] =Session.SessionID;
沒啟用 每次都會不同 ID
public class _Ag_Param
{
public string _SID;//使用者 id 紀錄就好 等登出時 再清掉
public double proValue = 0;
public string Dstr = "";
}
public class Pub_param//公用固定變數
{
public static List<_Ag_Param> Ag_Parm = new List<_Ag_Param>();
}
使用時用ID在 Pub_param.Ag_Parm.Add 加一個 ,
然後用 FIND 找 登出時記的移除 就好.
又是找了老半天 終於找到了
有個server 後端程式 需處理大量資料
雖然 可以 在前端 跑出 處理中.....
但是真的很久......
所以 "處理進度表" 是無法避免的 解決方案
我的解決方式是:
用 setInterval("Ckconnect()", 1000);
啟動一個 ajax
function Ckconnect() {
$.post("/Main/Ajax_DT", {})
.done(function (Rdata) {
var dta = Rdata.DT_STR.split('-');// replace('-',",");
var time = dta[0] + "/" + dta[1] + "/" + dta[2] + " " + dta[3] + ":" + dta[4] + ":" + dta[5];
$("#ckdt").text(time + ":" + Rdata.proValue);
$('#WaitP').progressbar('setValue', Rdata.proValue);
});
}
1秒去看一下 Rdata.proValue 處理進度值
而處理的話 也是 post 一個 資料回後端
$.post("/Main/Ajax_Wdata", {....})
後端就
while(...)
{
變更 Rdata.proValue; 值 讓前台知道
}
******************************************
一開始測都正常 ....
整個專案就在今天寫完測試時
突然發現 進度值 不動了 測試時間也不動了
確定是 "/Main/Ajax_DT" 沒回應
等 "/Main/Ajax_Wdata" 處理完後 時間才動
怎麼會變這樣....
***********************
用新的專案測試後
一個是隔 1秒用 $.post("/Main/Ajax_DT", {}) 去server 要時間
一個是故意 卡死一個 後端
public ActionResult Begin_Test()//卡死測試
{
while (true)
{
Pub_param.proValue++;
Thread.Sleep(1000);
if (Pub_param.Max_data == 100)
break;
}
return Json("OK");
}
是正常的
當 Begin_Test() 跑起來後
$.post("/Main/Ajax_DT", {}) 還是有正常回應
*****************************************
但是正式專案上就是 不回應了
經測試是 $.post("/Main/Ajax_DT", {})
一定要等 Begin_Test() 有 return 回到前台
Ajax_DT才會回來
一次只能回來一個就對了
****************************
但測試卻是可以的
這就非常奇怪了..........
經過不斷 交叉拆解 測試
一開始懷疑是 後端卡死 執行緒...但不是
是不是 jquery $.post 放置的地方或參數問題.....也不是
是 EasyUI 跟 $.post 卡住嗎?.....也不是
*******************************
就這樣....不斷不斷 試驗
終於在一個想都想不到的地方 抓到問題
就是 使用了 Session
public ActionResult CK_Tname(string Tname)
{
SData_SQL Mysd = new SData_SQL();
int Rcount = Mysd.Ck_Tname(Tname);
if (Rcount == 0)
Session["Tname"] = Tname;
return Json(Rcount);
}
*********************************
Session["Tname"] = Tname;
拿掉 就 正常(應該是 Action 不會排隊回來)
用 ViewData試 是OK
用 TempData 也是死 畢竟他也是 Session
********************************************
我猜應該是 Session 是公用變數
MVC 變成一次只能用一個 Action 去處理 怕2個同時會鎖死吧?我猜
********************************************
總之問題算是找到了
只要一用到 Session ,後面不管是否有再用到 都會變成這種狀況
一般應用應該是不會碰到這種問題
這次是我想用 "進度表" 特殊用法才會用到這問題
*****************************************************
知道後 找到的資料 早看到 就不用查這麼久
知道後 找到的資料 早看到 就不用查這麼久
但要小心 畢竟一些資料是存在 user端 容易被竄改 有時還會被擋
所以如不是非要用到 需要 2個 ajax 同時回應訊息且cookie資料不重要我才用
一般非必要我覺得我還是會用 Session
畢竟是安全 好處理 ,不用擔心用戶端封鎖cookie
記憶體問題? 能用錢解決的問題就不是問題
用戶同時連線都多到讓server 負擔不了的這種程度...還擔心錢?
+CPU+RAM+SSD ....這都比 資料安全性問題 簡單太多了
而且操作時點一下等一下(不要太久)是還好...
不用Session 不用 Cookies
但是還是要暫存資料做 Action之間 傳遞資料
我是想到一方法解決..
自己利用 session ID 做標記
寫一套 類似存放server端的cookie 來解決 傳遞問題
工程有點浩大還要做測試驗證
真碰到有需要再說
***************************************
另一種解決方案
是看到
在 ASP.NET MVC 中使用非同步控制器
AsyncController 類別這是另一種問題 我也沒碰過
有人實做過
非同步AsyncController + 網頁截圖 實作教學
這方法並不能解決 我的問題因為它是將 運行部分 丟到另一個執行緒去做 不占用web server
但還是要等他回來
所以他分2部分
public void 我的執行程式Async
public ActionResult 我的執行程式Completed
前端 ajax 還是 call "我的執行程式"還是等 我的執行程式Async 跑完 才會從 Completed return 回來
所以沒有解決這卡住問題
******************************
但這啟發我另一個想法 當還沒找到是Session 卡住時
就是 收到 Ajax 資料就丟給另一個 執行緒 跑,然後return 回來
射後不理..
讓另一個 Ajax 間隔1秒去 check 執行狀況
反正前方用 進度表擋住所有操作 等 執行緒通知 結束
再下一步就可以
這我有實做過類似的功能 但倒不是為了解決這問題
是為了解決 管控 多人同時處理資料庫 的問題用.
最後沒實作 是因 沒找到原因 心理總是毛毛的
畢竟應該是可以的 怎麼就突然卡死?
找不到 會不會 其他地方 死得更慘?
還好有找到
**********************
最後還是用了各人暫存表 來取代 session
使用方式
不能用 Session.SessionID;
Session.SessionID 要一致
就得啟用 Session
Session["id"] =Session.SessionID;
沒啟用 每次都會不同 ID
public class _Ag_Param
{
public string _SID;//使用者 id 紀錄就好 等登出時 再清掉
public double proValue = 0;
public string Dstr = "";
}
public class Pub_param//公用固定變數
{
public static List<_Ag_Param> Ag_Parm = new List<_Ag_Param>();
}
使用時用ID在 Pub_param.Ag_Parm.Add 加一個 ,
然後用 FIND 找 登出時記的移除 就好.
留言
張貼留言