请帮助我找到逻辑中的缺陷。我有两个名为“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);
}
}
答案 0 :(得分:3)
所以你在接下来建立字符串“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)进行比较 - 您偶尔可以为变量赋值。