最近作一个ASP.NET的项目,用到判断同时在线数的功能,就设计了个算法,程序如下://在线用户表
private static DataTable _onlineTable;
internal static DataTable OnlineTable
{
get
{
if ( _onlineTable == null )
{
_onlineTable = new DataTable();
_onlineTable.Columns.Add("clientIP"); //客户端IP
_onlineTable.Columns.Add("LastRequestTime"); //最后一次请求的时间
_onlineTable.AcceptChanges();
}
return _onlineTable;
}
}
//在线用户数
internal static int OnlineCount
{
get
{
return (OnlineTable == null) ? 0 : OnlineTable.Rows.Count;
}
}/// <summary>
/// 添加在线用户到列表
/// </summary>
private void AddOnlineUser()
{
string clientIP = Request.UserHostAddress;
DataRow curRow = OnlineTable.Rows.Find(new object[]{clientIP});
if(curRow == null)
{
//检查是否超过允许的最大用户数
if ( OnlineCount >= MAXNUM )
{
Response.Write(ERR_EXCEEDUSER);
Response.End();
} DataRow newRow = OnlineTable.NewRow();
newRow["clientIP"] = clientIP;
newRow["LastRequestTime"] = System.DateTime.Now;
OnlineTable.Rows.Add(newRow);
}
else
{
curRow["LastRequestTime"] = System.DateTime.Now;
} OnlineTable.AcceptChanges();
}
/// <summary>
/// 将断线用户删除出列表,超时时间为常量INTERVAL秒
/// </summary>
private void DeleteOfflineUser()
{
DateTime lastRequestTime;
DateTime expireTime = System.DateTime.Now.AddSeconds(-INTERVAL);
DataRow curRow = null;
if (OnlineCount == 0) return; string filter = "Convert(LastRequestTime, 'System.DateTime') < Convert('"
+ System.DateTime.Now.AddSeconds(-INTERVAL).ToString() + "', 'System.DateTime')"; DataRow[] offlineUsers = OnlineTable.Select(filter);
for( int i=0; i<offlineUsers.Length; i++ )
{
DataRow curRow = offlineUsers[i];
curRow.Delete();
} OnlineTable.AcceptChanges();
}//页面加载事件
protected override void OnLoad(EventArgs e){
DeleteOfflineUser();
AddOnlineUser();
}一般情况下都没有问题,运行OK,可是偶尔会出现如下错误:异常详细信息: System.NullReferenceException: 未将对象引用设置到对象的实例。
堆栈跟踪:
[NullReferenceException: 未将对象引用设置到对象的实例。]
System.Data.Select.FindSortIndex() +22
System.Data.Select.SelectRows() +237
System.Data.DataTable.Select(String filterExpression) +45
VOD.web.vodPage.DeleteOfflineUser()
VOD.web.vodPage.OnLoad(EventArgs e)
VOD.web.vodFeePage.OnLoad(EventArgs e)
System.Web.UI.Control.LoadRecursive() +35
System.Web.UI.Page.ProcessRequestMain() +731 经查,应该是运行DeleteOfflineUser函数的 DataRow[] offlineUsers = OnlineTable.Select(filter) 时产生的错误,可是这时候的OnlineTable肯定不为null,因为之前已经 if (OnlineCount == 0) return; 而且看堆栈跟踪信息,是运行到 System.Data.Select.FindSortIndex() 时出现了错误,由于这是类的内部函数,无法查看
只要杀了aspnt_wp进程后再刷新就正常了,可是连续运行一天或几天后就会再次出现,百思不得其解 在此向各位大侠请教求助~!!!!!只要有合理的答复通通给分,不够开版再加!!!!
private static DataTable _onlineTable;
internal static DataTable OnlineTable
{
get
{
if ( _onlineTable == null )
{
_onlineTable = new DataTable();
_onlineTable.Columns.Add("clientIP"); //客户端IP
_onlineTable.Columns.Add("LastRequestTime"); //最后一次请求的时间
_onlineTable.AcceptChanges();
}
return _onlineTable;
}
}
//在线用户数
internal static int OnlineCount
{
get
{
return (OnlineTable == null) ? 0 : OnlineTable.Rows.Count;
}
}/// <summary>
/// 添加在线用户到列表
/// </summary>
private void AddOnlineUser()
{
string clientIP = Request.UserHostAddress;
DataRow curRow = OnlineTable.Rows.Find(new object[]{clientIP});
if(curRow == null)
{
//检查是否超过允许的最大用户数
if ( OnlineCount >= MAXNUM )
{
Response.Write(ERR_EXCEEDUSER);
Response.End();
} DataRow newRow = OnlineTable.NewRow();
newRow["clientIP"] = clientIP;
newRow["LastRequestTime"] = System.DateTime.Now;
OnlineTable.Rows.Add(newRow);
}
else
{
curRow["LastRequestTime"] = System.DateTime.Now;
} OnlineTable.AcceptChanges();
}
/// <summary>
/// 将断线用户删除出列表,超时时间为常量INTERVAL秒
/// </summary>
private void DeleteOfflineUser()
{
DateTime lastRequestTime;
DateTime expireTime = System.DateTime.Now.AddSeconds(-INTERVAL);
DataRow curRow = null;
if (OnlineCount == 0) return; string filter = "Convert(LastRequestTime, 'System.DateTime') < Convert('"
+ System.DateTime.Now.AddSeconds(-INTERVAL).ToString() + "', 'System.DateTime')"; DataRow[] offlineUsers = OnlineTable.Select(filter);
for( int i=0; i<offlineUsers.Length; i++ )
{
DataRow curRow = offlineUsers[i];
curRow.Delete();
} OnlineTable.AcceptChanges();
}//页面加载事件
protected override void OnLoad(EventArgs e){
DeleteOfflineUser();
AddOnlineUser();
}一般情况下都没有问题,运行OK,可是偶尔会出现如下错误:异常详细信息: System.NullReferenceException: 未将对象引用设置到对象的实例。
堆栈跟踪:
[NullReferenceException: 未将对象引用设置到对象的实例。]
System.Data.Select.FindSortIndex() +22
System.Data.Select.SelectRows() +237
System.Data.DataTable.Select(String filterExpression) +45
VOD.web.vodPage.DeleteOfflineUser()
VOD.web.vodPage.OnLoad(EventArgs e)
VOD.web.vodFeePage.OnLoad(EventArgs e)
System.Web.UI.Control.LoadRecursive() +35
System.Web.UI.Page.ProcessRequestMain() +731 经查,应该是运行DeleteOfflineUser函数的 DataRow[] offlineUsers = OnlineTable.Select(filter) 时产生的错误,可是这时候的OnlineTable肯定不为null,因为之前已经 if (OnlineCount == 0) return; 而且看堆栈跟踪信息,是运行到 System.Data.Select.FindSortIndex() 时出现了错误,由于这是类的内部函数,无法查看
只要杀了aspnt_wp进程后再刷新就正常了,可是连续运行一天或几天后就会再次出现,百思不得其解 在此向各位大侠请教求助~!!!!!只要有合理的答复通通给分,不够开版再加!!!!
internal static int OnlineCount
{
get
{
return (OnlineTable == null) ? 0 : OnlineTable.Rows.Count;
}
}
这句没什么用了,直接return OnlineTable.Rows.Count好了。OnlineTable不可能为null了,在属性里已经判断如果是null就新建一个
最好用
Application.Lock();
..
Application.unlock();
lock(static_variable){
// your code here
}可能是你的OnlineTable为null导致的,你可以在使用该对象前做一个检查.
Application.Lock();
..
OnlineTable.
Application.unlock();