最近作一个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进程后再刷新就正常了,可是连续运行一天或几天后就会再次出现,百思不得其解  在此向各位大侠请教求助~!!!!!只要有合理的答复通通给分,不够开版再加!!!!

解决方案 »

  1.   

    没看出来,不过发现个别的问题
    internal static int OnlineCount
    {
      get
      {
        return (OnlineTable == null) ? 0 : OnlineTable.Rows.Count;
      }
    }
    这句没什么用了,直接return  OnlineTable.Rows.Count好了。OnlineTable不可能为null了,在属性里已经判断如果是null就新建一个
      

  2.   

    个人感觉,对static变量访问之前,尤其是写
    最好用
    Application.Lock();
    ..
    Application.unlock();
      

  3.   

    静态变量在做并发的时候最好使用
    lock(static_variable){
    // your code here
    }可能是你的OnlineTable为null导致的,你可以在使用该对象前做一个检查.
      

  4.   

    严重同意:
    Application.Lock();
    ..
    OnlineTable.
    Application.unlock();