2011-06-14 47 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)进行比较 - 您可以偶尔为变量赋值。