Member 12931315 Ответов: 1

Почему в то время как цикл зависания


Привет
Когда я пытаюсь преобразовать текстовый файл он идет на более чем 2000 строк и зависает
можете ли вы объяснить, почему ?

Заранее спасибо

Аджит

Что я уже пробовал:

DateTime datetime;

           OpenFileDialog choofdlog = new OpenFileDialog();
           choofdlog.Filter = "All Files (*.DAT)|*.DAT";
           choofdlog.FilterIndex = 1;
           choofdlog.Multiselect = true;
           string cToken;
           string cToken1;
           string cToken2;
           string cTime;
           string cDate;
           string cIdno;
           int nRecnt = 0;

           DataTable userdt = new DataTable();
           userdt = this.timeattDataSet.data  ;

           if (choofdlog.ShowDialog() == DialogResult.OK)
           {
               foreach (string sFileName in choofdlog.FileNames)
               {
                   using (FileStream fs = new FileStream(sFileName, FileMode.Open, FileAccess.Read))
                   {

                       StreamReader sr = new StreamReader(fs);

                       sr.BaseStream.Seek(0, SeekOrigin.Begin);

                       string str = sr.ReadLine();

                       while (str != null)

                       {

                           // Console.WriteLine(str);

                           str = sr.ReadLine();
                           if (str != null)
                           {
                               cToken1 = str.ToString().Substring(0, 9).Trim();
                               cToken2 = '5' + cToken1.PadLeft(5, '0');
                               cToken = cToken2.Substring(0, 6);
                               cDate = str.ToString().Substring(10, 10);
                               cTime = str.ToString().Substring(21, 2) + str.ToString().Substring(24, 2);
                               cIdno = str.ToString().Substring(30, 1);
                               datetime = System.Convert.ToDateTime(cDate);

                               nRecnt = nRecnt + 1;
                               this.textBox2.Text = nRecnt.ToString();
                               this.textBox2.Refresh();

                               string queryString = "Token_no = '" + cToken + "' AND Date = '" + datetime +"' AND Time ='" + cTime + "'";
                               bool rowExists = userdt.AsEnumerable().Any(row => string.Equals(row.Field<string>("Token_no"), cToken, StringComparison.OrdinalIgnoreCase) && row.Field<DateTime>("Date") == datetime && row.Field<string>("Time") == cTime);

                               if (rowExists == false)
                                   {
                                       this.textBox1.Text = cToken + '-'+ datetime;
                                       this.textBox1.Refresh();
                                       DataRow newCustomersRow = this.timeattDataSet.Tables["data"].NewRow();
                                       newCustomersRow["Token_no"] = cToken;
                                       newCustomersRow["Date"] = datetime;
                                       newCustomersRow["Time"] = cTime;
                                       newCustomersRow["Terminal"] = cIdno;
                                       newCustomersRow["Mode"] = "T";
                                       newCustomersRow["In_out"] = "";
                                       newCustomersRow["Updated"] = false;

                             }

                           }
                           else
                           {
                               break;
                           }
                       }

                       sr.Close();

                       fs.Close();

                   }
               }

           }

ZurdoDev

Что значит "повесить трубку"?" Если вы имеете в виду, что пользовательский интерфейс перестает реагировать, то это потому, что вы делаете это в потоке пользовательского интерфейса, так что именно это и произойдет.

phil.o

Вы не должны вызывать метод ToString () для строковой переменной.
И если есть много файлов и/или у них есть много строк, то перемещение всего процесса в фоновый поток оставит ваш пользовательский интерфейс отзывчивым.

1 Ответов

Рейтинг:
1

OriginalGriff

Когда вы пишете приложение Windows, оно начинается с одного потока, что означает, что оно может делать одну вещь одновременно. Если вы заняты чтением и обработкой строк из файла, то ваше приложение не может делать ничего другого, пока вы не закончите это делать - и это включает в себя не реагирование на ввод пользователя или запросы на изменение дисплея: потому что Windows работает, отправляя сообщения вашему приложению, которые оно обрабатывает, когда возвращается к своему "циклу ожидания" и ищет, что бы сделать. Если вы держите его занятым просмотром строк из файлов, то у него никогда не кончаются дела и он никогда не смотрит на свою коллекцию сообщений.

Поэтому вместо этого вам нужно запустить второй поток, чтобы сделать всю "ослиную работу" за кулисами. Но это создает свои собственные проблемы, потому что вы можете получить доступ к элементам управления дисплеем только из одного потока - потока пользовательского интерфейса, с которого началось ваше приложение. Например, если вы попытаетесь изменить текст в текстовом поле из другого потока, вы получите "исключение перекрестной потоковой передачи", и ваше приложение потерпит неудачу. Есть способы обойти это - это называется вызовом контроля, - но это становится сложным для объяснения.

Поэтому вместо этого посмотрите на Класс BackgroundWorker (System.ComponentModel)[^]- это позволяет вам очень просто настроить второй поток и сообщить о событиях прогресса обратно в основной поток, чтобы он мог обновить элементы управления, чтобы отразить его. Взгляните на этот пример, а также на ProgressChangedEventArgs, поскольку существует свойство UserState, которое позволяет вам отправлять обратно сложную информацию о том, как продвигается задание в ваш основной поток.


Member 12931315

Спасибо Гриффу, Райану, Филу, я попробую

OriginalGriff

Пожалуйста!