問題描述
1.線程被中斷,沒執行完
2.全局變量值和Session值丟失
IIS設置和w3wp.exe進程如下圖
1.關閉時間限制(秒) 90秒,閒置逾時20分鐘 意思大概是網頁請求閒置20分鐘后將在90秒之後自動關閉w3wp.exe進程
測試設定將 90改成30,20改成1
2.固定時間間隔 1740分鐘 大概29小時, 意思大概是w3wp.exe進程運行29小時后,會自動回收
測試設定將1740改成5
測試案例
1.ajax請求執行線程(test按鈕)
a.點一次test按鈕 大概在2分鐘左右時w3wp.exe自動關閉了,Thread線程停止工作,沒有異常產生,且Session和全局變量SessionHelper.SessionHelper.TestStr值丟失
b.頻繁點擊test按鈕 大概在5分鐘左右時 w3wp.exe出現兩個即IIS自動回收生效,第一個w3wp.exe內存慢慢減少至消失,Thread線程停止工作,沒有異常產生,且Session和全局變量SessionHelper.SessionHelper.TestStr值丟失一次時
2.Ajax請求 長時間運行 (Sleep按鈕) 耗時4分鐘
a.開啟后立即點一次test按鈕 w3wp.exe在5分30秒后才消失,即直到Sleep返回后連接才被閒置
b.開啟后在w3wp.exe消失前點擊一次,在5分鐘左右時間時,w3wp.exe出現兩個即IIS自動回收生效,兩個w3wp.exe一直存在直到Sleep請求執行完畢時,第一個w3wp.exe才消失
結論:
1.IIS自動回收和自動關閉會將 多線程,全局變量,Session清空
2.耗時的請求會阻止IIS的自動回收和自動關閉
3.網頁在使用多線程,全局變量及Session時,要考慮使用的安全性,防止丟失造成網頁異常
主要測試代碼
JS代碼
//異步Ajax
AjaxHelper.PostCallback = function (RequestControl, PostData,CallBack) {
$.ajax({
type: "POST",
url: RequestControl,
data: PostData,
dataType: "jsonp",
async: true,//異步
success: function (result) {
CallBack(result);
},
error: function (xhr) {
if (xhr.status == "0" && (!(location.href.indexOf("localhost") > -1 || location.href.indexOf("log=Y") > -1))) {
return;
}
alert("PostCallback status:" + xhr.status + "statusText:" + xhr.statusText + "responseText:" + xhr.responseText);
}
});
}
$("#test").click(function () {
var pd = { action: "run"}
AjaxHelper.PostCallback("handler/Handler.ashx", pd, function (a) {
alert(a);
});
});
$("#Sleep").click(function () {
var pd = { action: "Sleep" }
AjaxHelper.PostCallback("handler/Handler.ashx", pd, function (a) {
alert(a);
});
});
Session操作類
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Web;
using System.Web.SessionState;
using WebPublic;
namespace SessionHelper
{
public class SessionHelper : IRequiresSessionState
{
public static HttpSessionState MSession = HttpContext.Current.Session;
public static void InitSesion(HttpSessionState _session)
{
if (SessionHelper.MSession != null)
{
SessionHelper.MSession = _session;
}
}
public static string TestStr;
public static string GetSession(string key)
{
try
{
return PubString.ToString(SessionHelper.MSession[key]);
}
catch (Exception ex)
{
LogHelper.WriteLog("GetSession", "Err", ex);
throw ex;
}
}
public static void SetSession(string key, string value)
{
try
{
SessionHelper.MSession[key] = value;
}
catch (Exception ex)
{
LogHelper.WriteLog("GetSession", "Err", ex);
throw ex;
}
}
}
}
public string TestRun()
{
try
{
string _str = SessionHelper.SessionHelper.GetSession("test");
if (_str != "")
{
SessionHelper.SessionHelper.SetSession("test", (int.Parse(_str) + 1).ToString());
}
else
{
_str = "0";
SessionHelper.SessionHelper.SetSession("test", (int.Parse(_str) + 1).ToString());
}
SessionHelper.SessionHelper.TestStr = "值為null是,表明被清空";
Thread m_SplashThread = new Thread(new ThreadStart(delegate()
{
try
{
for (int i = 0; i < 60; i++)
{
Thread.Sleep(60000);//1分
SessionHelper.SessionHelper.SetSession("test-" + (int.Parse(_str) + 1) + "_" + i, "測試字符串----");
LogHelper.WriteLog("一分鐘斷線", SessionHelper.SessionHelper.TestStr, SessionHelper.SessionHelper.MSession.Count.ToString());
}
LogHelper.WriteLog("一分鐘斷線", SessionHelper.SessionHelper.TestStr, SessionHelper.SessionHelper.MSession.Count.ToString());
}
catch (Exception ex)
{
LogHelper.WriteLog("一分鐘斷線", "Err", ex);
}
}));
m_SplashThread.IsBackground = true;
m_SplashThread.SetApartmentState(ApartmentState.STA);
m_SplashThread.Start();
return _str;
}
catch (Exception ex)
{
LogHelper.WriteLog("TestRun", "Err", ex);
throw ex;
}
}
public string Sleep() {
//持續請求 2分
try
{
string _str = SessionHelper.SessionHelper.GetSession("test");
if (_str != "")
{
SessionHelper.SessionHelper.SetSession("test", (int.Parse(_str) + 1).ToString());
}
else
{
_str = "0";
SessionHelper.SessionHelper.SetSession("test", (int.Parse(_str) + 1).ToString());
}
//SessionHelper.SessionHelper.TestStr = "值為null是,表明被清空";
Thread.Sleep(240000);//持續請求 4分
LogHelper.WriteLog("TestRun", SessionHelper.SessionHelper.TestStr, _str);
return SessionHelper.SessionHelper.TestStr;
}
catch (Exception ex)
{
LogHelper.WriteLog("TestRun", "Err", ex);
throw ex;
}
}