我的程序逻辑有什么问题

时间:2011-06-14 07:42:39

标签: c# database loops logic

请帮助我找到逻辑中的缺陷。我有两个名为“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 个答案:

答案 0 :(得分: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 :(得分: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;
}

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