【问题标题】:What is wrong with my program logic我的程序逻辑有什么问题
【发布时间】:2011-06-14 07:42:38
【问题描述】:

请帮我找出我的逻辑缺陷。我有两个名为“prev”和“next”的变量......我基本上做的是每 5 秒从我的数据库中读取一次数据,如果 next 和 prev 不相等,则使用 Websync 服务器将其打印出来。我的数据库中有两行。好像

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);

            }
        }

【问题讨论】:

  • 你试过使用调试器吗?
  • 是的。逻辑上没有错误。我猜这只是数据连接的方式
  • 我们这里不使用 pastebin。将代码直接添加到问题中,并且只添加相关部分而不是所有代码。
  • 我认为你应该在while ((reader.Read()))之前清除next
  • @Reniuz:我正在这样做。在 Thread.sleep(5000) 之上,我给出 prev=String.Copy(next);和 next=String.Copy("");

标签: c# database loops logic


【解决方案1】:

Renuiz 在评论中回答了它,但这是因为你没有下一个清除。

因此,您在 next 中构建字符串“8 10”,将其存储在 prev 中。下次您将“8 10”与下一个连接时,生成“8 10 8 10”。这是不同的,所以你打印它。

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

这是该循环的结束。你真的应该在循环开始时清除下一个。

你也可以只设置字符串

next = String.Empty;

我会在你的 while 循环中声明 next,因为你在更大的范围内不需要它,我会称之为 current 而不是 next。

【讨论】:

    【解决方案2】:

    你的程序逻辑真的有什么问题——逻辑不明显。它是如此模糊,以至于您无法理解错误在哪里。因此,我的建议如下 - 如果您找不到错误,请尝试简化您的代码。

    目前,您的方法有很多职责 - 它查询数据库、将数据转储到文件、在某处发布数据并记录结果。你坚持所有这些东西。如果有人需要更改数据库查询或发布逻辑 - 他将需要查看所有其他内容。

    所以,先分离逻辑:

    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);
       }
    }
    

    好吧,我对您的域了解不多,因此您可能可以考虑为变量和方法取更好的名称。

    在这里,您将数据访问逻辑提取到单独的方法中(重构的第一步和小型应用程序都可以)。请记住,将连接对象包装到 using 块中可以保证在出现异常时关闭连接:

    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;
    }
    

    下一步 - 将 id 连接成一个字符串的简单方法:

    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) - 您可以偶尔为变量赋值。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2016-12-15
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-10-01
      • 1970-01-01
      • 1970-01-01
      • 2019-03-05
      相关资源
      最近更新 更多