2013-08-05 56 views
1

在行foreach (DataRow Row in Table.Rows)中,我收到NullReferenceException。對「Table.Rows」的foreach中的空引用

該程序在C#中的模擬器中。當我調試它並崩潰時,它以黃色突出顯示單詞foreach。我在下面粘貼了我的整個代碼。

using System; 
using System.Collections.Generic; 
using System.Data; 

using Reality.Storage; 
using System.Threading; 

namespace Reality.Game.Moderation 
{ 
    public static class ModerationBanManager 
    { 
     private static List<uint> mCharacterBlacklist; 
     private static List<string> mRemoteAddressBlacklist; 
     private static Thread mWorkerThread; 
     private static object mSyncRoot; 

     public static void Initialize(SqlDatabaseClient MySqlClient) 
     { 
      mCharacterBlacklist = new List<uint>(); 
      mRemoteAddressBlacklist = new List<string>(); 
      mSyncRoot = new object(); 

      mWorkerThread = new Thread(new ThreadStart(ProcessThread)); 
      mWorkerThread.Name = "ModerationBanManager"; 
      mWorkerThread.Priority = ThreadPriority.Lowest; 
      mWorkerThread.Start(); 

      ReloadCache(MySqlClient); 
     } 

     public static void ProcessThread() 
     { 
      try 
      { 
       while (Program.Alive) 
       { 
        Thread.Sleep(600000); 

        using (SqlDatabaseClient MySqlClient = SqlDatabaseManager.GetClient()) 
        { 
         ReloadCache(MySqlClient); 
        } 
       } 
      } 
      catch (ThreadAbortException) { } 
      catch (ThreadInterruptedException) { } 
     } 

     public static void ReloadCache(SqlDatabaseClient MySqlClient) 
     { 
      lock (mSyncRoot) 
      { 
       mCharacterBlacklist.Clear(); 
       mRemoteAddressBlacklist.Clear(); 

       MySqlClient.SetParameter("timestamp", UnixTimestamp.GetCurrent()); 
       DataTable Table = MySqlClient.ExecuteQueryTable("SELECT * FROM bans WHERE timestamp_expire > @timestamp"); 

       foreach (DataRow Row in Table.Rows) 
       { 
        uint UserId = (uint)Row["user_id"]; 
        string RemoteAddr = (string)Row["remote_address"]; 

        if (UserId > 0 && !mCharacterBlacklist.Contains(UserId)) 
        { 
         mCharacterBlacklist.Add(UserId); 
        } 

        if (RemoteAddr.Length > 0 && !mRemoteAddressBlacklist.Contains(RemoteAddr)) 
        { 
         mRemoteAddressBlacklist.Add(RemoteAddr); 
        } 
       } 
      } 
     } 

     public static bool IsRemoteAddressBlacklisted(string RemoteAddressString) 
     { 
      lock (mSyncRoot) 
      { 
       return mRemoteAddressBlacklist.Contains(RemoteAddressString); 
      } 
     } 

     public static bool IsUserIdBlacklisted(uint UserId) 
     { 
      lock (mSyncRoot) 
      { 
       return mCharacterBlacklist.Contains(UserId); 
      } 
     } 

     public static void BanUser(SqlDatabaseClient MySqlClient, uint UserId, string MessageText, uint ModeratorId) 
     { 
      MySqlClient.SetParameter("userid", UserId); 
      MySqlClient.SetParameter("reason", MessageText); 
      MySqlClient.SetParameter("timestamp", UnixTimestamp.GetCurrent()); 
      MySqlClient.SetParameter("timestampex", UnixTimestamp.GetCurrent()); 
      MySqlClient.SetParameter("moderator", ModeratorId); 
      MySqlClient.ExecuteNonQuery("INSERT INTO bans (user_id,reason_text,timestamp_created,timestamp_expire,moderator_id) VALUES (@userid,@reason,@timestamp,@timestampex,@moderator)"); 

      lock (mSyncRoot) 
      { 
       mCharacterBlacklist.Add(UserId); 
      } 
     } 
    } 
} 
+6

大多數人不會通過這個多碼讀取。嘗試發佈最少量的代碼來說明你的問題 – bengoesboom

+0

'DataTable Table'你應該重命名這個變量不與類名'Table'衝突 – Shoe

回答

4

如果您在精確的線有NullReferenceException異常,這意味着,無論是Table變量或Rows屬性是null。幾乎沒有其他選擇。請在那裏放置一個斷點並檢查其中哪一個爲空 - 然後調查並糾正它。

5

如果它真的被這行拋出:

foreach (DataRow Row in Table.Rows) 

然後TableTable.Rows爲空。如果它從您的foreach循環中拋出:

foreach (DataRow Row in Table.Rows) 
{ 
    //aka in here 
} 

那麼它最有可能意味着您的行之一爲空。要找到哪一個在你的循環的開始處添加它,並在if語句內放置一個斷點。

foreach (DataRow Row in Table.Rows) 
{ 
    if(Row == null) 
    { 
     //breakpoint here! 
    } 

} 

您還可以在調試時檢查Table.Rows,但如果有1000行,這不是一個現實的選擇。

+1

順便說一句,foreach也會拋出當'行'爲空 – quetzalcoatl

+0

當你說/ /斷點在這裏!,我將不得不編碼斷點?或者只是添加該代碼..對不起,如果我似乎不知道很多我基本與C# –

+0

只需右鍵點擊你想要的斷點,鼠標在「斷點」子菜單上,並選擇「插入斷點」。 –

1

我想象中會拋出一個空引用異常的唯一情況是,如果Tablenull

foreach (DataRow Row in Table.Rows) 

當異常被拋出而行被突出顯示,你在調試器。

當您在調試器中時,在屏幕的最底部,您會看到一個名爲WatchWatch的選項卡。點擊該選項卡。

在底部的框中​​,鍵入單詞Table,然後按回車鍵,它會顯示您的值Table我敢打賭這是空的。

0

你有沒有調試過,並確保你的DataTable不是實際爲空?

以下情況會返回什麼結果?你的問題很可能在該行的代碼,而不是在對/每

DataTable Table = MySqlClient.ExecuteQueryTable("SELECT * FROM bans WHERE timestamp_expire > @timestamp"); 
1

按照DataTable documentation,你調用構造函數期待一個String對象爲要使用的名稱表。它實際上並沒有加載表格。

使用DataTable的最佳方式是初始化DataTable(例如,DataTable table = new DataTable()),然後使用Rows屬性的.Add()方法添加到它。爲了說明這一點,你可以使用下面的代碼foreach循環通過MySQL查詢結果迭代裏面:

table.Rows.Add(item)

相關問題