Что на самом деле не так с вашей логикой программы - логика не очевидна.Это так неясно, что вы не можете понять, где ошибка.Итак, мой совет следующий: если вы не можете найти ошибку, попробуйте упростить ваш код.
В настоящее время у вашего метода много обязанностей - он запрашивает базу данных, выдает данные в файл, публикует данные где-то ипротоколирует результаты.И ты застрял со всем этим.Если кому-то понадобится изменить запрос к базе данных или опубликовать логику - ему нужно будет пересмотреть все остальные вещи.
Итак, сначала отдельная логика:
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;
}
Далее - простой способ объединения идентификаторов в одну строку:
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 старайтесь избегать сравнения логических переменных с истиной / ложью (публикация. Успех == истина) - вы можетеиногда присваивайте значение вашей переменной.