2011-06-14 48 views
0

請幫我找到我的邏輯中的缺陷。我有兩個變量名爲「prev」和「next」...我基本上做的是每5秒從數據庫中讀取數據,並使用Websync服務器打印出來,如果next和prev不相等。我的數據庫中有兩行。它看起來像我的程序邏輯有什麼問題

ID 
8 
10 

這裏是鏈接到代碼http://pastebin.com/Hb3eH2Qv

當我運行我的程序,我得到的結果作爲

8 10 8 10 
8 10 
8 10 8 10 
8 10 

......(依此類推)

但是,結果應該只是

8 10 

我不知道如何8 10 8 10出現。數據被連接兩次。

注意:您可以只看到PublishLoop()功能

private void PublishLoop() 
     { 
      String prev=String.Copy(""); 
      String next=String.Copy(""); 
      String ConnectionString = ConfigurationManager.ConnectionStrings["MyDbConn"].ToString(); 
      SqlConnection connection = new SqlConnection(ConnectionString); 
      SqlCommand command = connection.CreateCommand(); 
      command.CommandText = "select ID from Tab1"; 
      command.Notification = null; 

      while (Running) 
      { 
       connection.Open(); 
       using (SqlDataReader reader = command.ExecuteReader(CommandBehavior.CloseConnection)) 
       { 
        StreamWriter sw1 = new StreamWriter("C:\\Users\\Thothathri\\Desktop\\next.txt"); 
        while ((reader.Read())) 
        { 
         //Response.Write(reader[0].ToString()); 
         next = String.Concat(next,reader[0].ToString()); 
         sw1.WriteLine(next); 

        } 
        sw1.Close(); 


        if (!prev.Equals(next)) 
        { 
         Publisher publisher = new Publisher(new PublisherArgs 
         { 
          DomainKey = "c80cb405-eb77-4574-9405-5ba51832f5e6", 
          DomainName="localhost" 
         }); 
         Publication publication = publisher.Publish("/test", JSON.Serialize(next)); 
         if (publication.Successful == true) 
         { 
          StreamWriter sw = new StreamWriter("C:\\Users\\Thothathri\\Desktop\\error123.txt"); 
          sw.WriteLine("success"); 
          sw.WriteLine(next); 
          sw.Close(); 
         } 
         else 
         { 
          StreamWriter sw = new StreamWriter("C:\\Users\\Thothathri\\Desktop\\error123.txt"); 
          sw.Write("failed"); 
          sw.Close(); 
         } 
         prev = String.Copy(next); 
         next = String.Copy(""); 
        } 


       } 
       Thread.Sleep(5000); 

      } 
     } 
+2

您是否嘗試過使用調試器? – 2011-06-14 07:44:48

+0

是的。邏輯上沒有錯誤。它只是在數據串聯的方式,我猜 – CuriousCoder 2011-06-14 07:45:42

+6

我們不使用pastebin在這裏。直接添加代碼到問題中,只添加相關部分而不是全部代碼。 – jgauffin 2011-06-14 07:46:15

回答

3

Renuiz回答了在註釋中的代碼,但是那是因爲你沒有一個結算。

所以你在下一步建立字符串「8 10」,將它存儲在prev中。下一次你用接下來連接「8 10」,製作「8 10 8 10」。這是不同的,所以你打印它。

   if (!prev.Equals(next)) 
       { 
.... 
        prev = String.Copy(next); 
        next = String.Copy(""); 
       } 

這是該循環的結束。您應該在該循環的開始處真正清除下一個。

你也可以只設置該字符串

next = String.Empty; 

我接下來會宣佈while循環裏面,因爲你不需要它在更大的範圍內,我把它叫做電流而不是未來。

1

你的程序邏輯真的有問題 - 邏輯不明顯。它太模糊了,你無法理解錯誤在哪裏。所以,我的建議是 - 如果你找不到錯誤,試着簡化你的代碼。

當前你的方法有很多責任 - 它查詢數據庫,將數據轉儲到文件,它將數據發佈到某處並記錄結果。而你堅持所有這些東西。如果有人需要更改數據庫查詢或發佈邏輯 - 他將需要檢查所有其他內容。

所以,獨立的邏輯首先:

private void PublishLoop() 
{ 
    string previousIDs = String.Empty; 
    int timeout = Int32.Parse(ConfigurationManager.AppSettings["publishTimeout"]); 

    while (Running) 
    {     
     string currentIDs = ConcatenateList(LoadIDs()); 
     Dump(currentIDs); 

     if (!previousIDs.Equals(currentIDs)) 
     { 
      try 
      { 
       Publish(currentIDs); 
       _log.Info("Published successfuly"); 
      } 
      catch (PublicationException exception) 
      { 
       _log.Error("Publication failed"); 
      } 

      previousIDs = currentIDs; 
     } 

     Thread.Sleep(timeout); 
    } 
} 

好了,我不知道很多關於你的域名,所以你可能可以考慮一下變量和方法更好的名字。

在這裏,您已經將數據訪問邏輯解壓縮到單獨的方法(對於重構和小應用程序的第一步可以使用)。請記住,該包裝連接對象爲使用塊保證連接將在例外的情況下被關閉:

private IList<int> LoadIDs() 
{ 
    List<int> ids = new List<int>(); 

    String connectionString = ConfigurationManager.ConnectionStrings["MyDbConn"].ConnectionString; 
    using (SqlConnection connection = new SqlConnection(connectionString)) 
    { 
     SqlCommand command = connection.CreateCommand(); 
     command.CommandText = "select ID from Tab1"; 
     command.Notification = null; 

     connection.Open(); 
     using (SqlDataReader reader = command.ExecuteReader(CommandBehavior.CloseConnection)) 
     { 
      while ((reader.Read())) 
       ids.Add((int)reader["ID"]); 
     } 
    } 

    return ids; 
} 

下一頁 - 簡單方法來串聯IDS成一個字符串:

private string ConcatenateList(IList<int> values) 
{ 
    return String.Join(" ", values.Select(value => value.ToString()).ToArray()); 
} 

轉儲(記,該文件名移動到配置文件):

private void Dump(string ids) 
{    
    using (StreamWriter writer = new StreamWriter(ConfigurationManager.AppSettings["dumpFilePath"])) 
     writer.WriteLine(ids); 
} 

和發佈邏輯:

private void Publish(string ids) 
{ 
    PublisherArgs args = new PublisherArgs 
    { 
     DomainKey = "c80cb405-eb77-4574-9405-5ba51832f5e6", 
     DomainName = "localhost" 
    }; 

    Publisher publisher = new Publisher(args); 
    Publication publication = publisher.Publish("/test", JSON.Serialize(ids)); 

    if (!publication.Successful) 
     throw new PublicationException(); 
} 

我認爲,失敗是例外,他們不經常發生(所以我決定在這種情況下使用例外)。但如果它是普通的東西 - 你可以簡單地使用像TryPublish這樣的布爾方法。

順便說一句,你可以使用一些日誌庫,如log4net記錄成功和失敗發佈。或者你可以提取日誌邏輯來分離方法 - 這將使主邏輯更清晰,更易於理解。

PS儘量避免將布爾變量與true/false(publication.Successful == true)進行比較 - 您可以偶爾爲變量賦值。