Что не так с моей логикой программы - PullRequest
0 голосов
/ 14 июня 2011

Пожалуйста, помогите мне найти дефект в моей логике.У меня есть две переменные с именами «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 ]

3 голосов
/ 14 июня 2011

Ренуиз ответил на это в комментарии, но это потому, что вы не очищаете следующий.

Таким образом, вы строите строку "8 10" в следующем, сохраните ее в пред.В следующий раз вы согласуете «8 10» со следующим, делая «8 10 8 10».Что отличается, поэтому вы печатаете его.

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

Это конец этого цикла.Вы действительно должны очистить следующий в начале этого цикла.

Также вы можете просто установить строку

next = String.Empty;

Я бы объявил следующее внутри вашего цикла while, так как вам не нужноэто в большем объеме, и я бы назвал это текущим, а не следующим.

1 голос
/ 14 июня 2011

Что на самом деле не так с вашей логикой программы - логика не очевидна.Это так неясно, что вы не можете понять, где ошибка.Итак, мой совет следующий: если вы не можете найти ошибку, попробуйте упростить ваш код.

В настоящее время у вашего метода много обязанностей - он запрашивает базу данных, выдает данные в файл, публикует данные где-то ипротоколирует результаты.И ты застрял со всем этим.Если кому-то понадобится изменить запрос к базе данных или опубликовать логику - ему нужно будет пересмотреть все остальные вещи.

Итак, сначала отдельная логика:

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 старайтесь избегать сравнения логических переменных с истиной / ложью (публикация. Успех == истина) - вы можетеиногда присваивайте значение вашей переменной.

...