2014-01-11 3 views
0

Мое приложение заполнено на 95%, и теперь я на стадии тестирования.
Я использовал файл .exe в папке отладки, затем я использую приложение для сохранения определенной строки из строки строки от модуля GPS, чтобы получить доступ к базе данных ..
Вот ПотокНевидимая ошибка, приложение stucks

образца данных
enter image description here
от GPRMC до GPGSA = 1second интервал. Таким образом, технический модуль посылает три строки каждую секунду.

Try 
Dim fruit As String = "$GPRMC" 

      For Each line As String In RichTextBox1.Lines 
       If line.Contains(fruit) Then 
        ProgressBar1.Value = 0 
        txt = line.Split(","c) 
        Insert() 
       End If 
      Next 
Catch ex As Exception 
     sPort.Close() 
     MessageBox.Show("There had been no data received.", Me.Text, MessageBoxButtons.RetryCancel) 
     Call btnStartTimer_Click(sender, New EventArgs) 
    End Try 

Под Minute_Tick, каждый 60с, Second.Start (, который является выше код). Каждую минуту я очищаю RichTextBox, а затем через 2 секунды (rtb заполняется снова). Я получаю строку с $GPRMC в ней, а .Split - до массива ~ txt(). Впредь у меня есть слова, разделенные комой в массиве.

Теперь я добавить его в базу данных:

' Now inside a Using block 
      If txt(3) = String.Empty Then 
       .AddWithValue("@lat", 0) 
      Else 
       Dim la As Double = Double.Parse(txt(3).Substring(0, 2)) + Double.Parse(txt(3).Substring(2))/60.0 
       .AddWithValue("@lat", la) 
      End If 

txt(3) является Latitude формат DMS, поэтому я добавил немного превращающего сниппет. Он отлично работает, хотя я добавил условие, чтобы убедиться, что оно не будет вычисляться для значения null или 0.

UPDATE (я не могу понять этот код, потому что я просто скопировал его, но он отлично работает с последним приложением, которое я создал.)

Delegate Sub SetTextCallback(ByVal [text] As String) 
Dim x As New SetTextCallback(AddressOf ReceivedText) 
Private Sub SerialPort1_DataReceived(ByVal sender As Object, ByVal e As System.IO.Ports.SerialDataReceivedEventArgs) Handles sPort.DataReceived 
    ReceivedText(sPort.ReadExisting) 
End Sub 
Private Sub ReceivedText(ByVal [text] As String) 
    If Me.RichTextBox1.InvokeRequired Then 
     Me.Invoke(x, New Object() {(text)}) 
    Else 
     Me.RichTextBox1.Text &= [text] 
    End If 
End Sub 

Смутного Я нашел
Я испытываю что-то вроде Threading Sleep. Приложение зависает, не может щелкнуть, не может закрыть, но его «запустить» в диспетчере задач, поэтому я думаю, что он находится в бесконечном цикле, или я ошибаюсь? Я закончил его закрытие в диспетчере задач и снова открыл его. Бежит ровно .. тогда позже он застрянет.
Я думал и до сих пор, что его вызывает? Я думал, потому что модуль не всегда может получить сигнал, поэтому он ничего не возвращает ... но он сохраняет 0 в БД (код выше), если модуль не дал координат, поэтому в этом нет никаких проблем.

Можете ли вы, ребята, помочь мне виновником? Я нахожусь на третий день, поэтому решил, что мне нужна помощь. Благодарю. Дайте мне знать, если вам нужно что-нибудь или какие-то разъяснения.

+0

как вы использовали try..catch заявление, и очень сложно проанализировать фрагмент кода, который вы предоставили. – Jade

+0

Проверить обновление кода. код преобразования, заключается в преобразовании формата DMS кодов, переданных мне в десятичные координаты, которые читаются API, которые я использую. – AdorableVB

+0

Что-то не так в переменной txt (3), поскольку она анализируется. Таким образом, возможно, что значение широты не то, что вы ожидаете. Попытайтесь записать эти значения в каком-то файле и проверьте значения, которые приводят к сбою вашей программы. Кстати, какое именно сообщение об ошибке получено? – Steve

ответ

5
If Me.RichTextBox1.InvokeRequired Then 
    Me.Invoke(x, New Object() {(text)}) 
Else 
    Me.RichTextBox1.Text &= [text] 
End If 

Ваш код делает это:

enter image description here

Это Firehose проблема. Проблема началась с вызова SerialPort.ReadExisting(). Обычно это возвращает один или два символа, последовательные порты довольно медленные. При общей настройке Baudrate, равной 9600 бод, вы получаете 1000 символов в секунду, чтобы эффективно добавлять новый текст в RichTextBox примерно 500 раз в секунду, давать или принимать.

Это заставляет RichTextBox переназначать свой внутренний буфер, который хранит текст и освобождает место для дополнительных добавленных символов, а затем копирует весь существующий текст из старого буфера в новый буфер и добавляет новый текст. Затем обновите экран.

Это происходит довольно гладко, когда вы впервые запускаете свою программу, RichTextBox не содержит много текста. Но становится все дороже, все больше и больше символов нужно копировать.

До тех пор пока вы не достигнете критической точки, где копирование начнет занимать слишком много времени, больше времени, чем скорость, с которой вы вызываете Me.Invoke(). Теперь поток пользовательского интерфейса начинает отставать, и он никогда не сможет идти в ногу со временем. Как пытаясь выпить из пожарного шланга. Как только выполняется копирование внутреннего буфера, необходимо отправить другой запрос на вызовы, заставив буфер повторно перераспределить.

Теперь пользовательский интерфейс перестает выполнять свои обычные обязанности с более низким приоритетом. Который включает обновление экрана и обработку входных событий. Вы замечаете это из своей действующей заморозки, как будто она зашла в тупик. Windows заменяет ваше главное окно окном призрака, в котором говорится: «Не реагировать», а удар по мыши или клавиатуре не влияет. Все, что вы можете сделать, это прекратить работу программы с помощью отладчика или диспетчера задач и перезапустить ее. Что хорошо работает, RichTextBox снова имеет пустой буфер, и копирование снова дешево.

Обратите внимание, что это общая проблема при обработке строк. Для решения этой проблемы .NET Framework имеет класс StringBuilder. Однако для RichTextBox это не доступно, вам нужно найти другое решение.

так что вы эффективно добавить новый текст в RichTextBox около 500 раз в секунду

Вы должны решить, что проблема. Нет смысла добавлять текст в RTB с такой скоростью, ни один человек никогда не сможет наблюдать такой высокий уровень. Добавление текста 20 раз в секунду уже достаточно быстро, оно начинает выглядеть как размытие, когда вы делаете это быстрее, чем это. Или, другими словами, прямо сейчас вы делаете это в 25 раз быстрее, чем необходимо. Предоставление как RTB, так и потока пользовательского интерфейса с трудом выдерживает эту скорость.

Также обратите внимание, что это объясняет вашу проблему синтаксического анализа. Вы разбираете неполную строку текста. Таким образом, исправление первого порядка для этого состоит в том, чтобы вызывать только при получении полной строки текста из последовательного порта. Это очень легко прийти:

Private Sub SerialPort1_DataReceived(ByVal sender As Object, ByVal e As System.IO.Ports.SerialDataReceivedEventArgs) Handles sPort.DataReceived 
    ReceivedText(sPort.ReadLine) 
End Sub 

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

Еще две вещи, которые вам нужно сделать. Ваша программа по-прежнему будет зависать, когда она работает достаточно долго. Вам действительно нужно ограничить количество текста в RTB. Просто выбросьте половину его, когда он хранит больше, чем, скажем, 65000 символов. И вы должны удалить вызовы метода Close(), что вызовет реальный тупик, потому что порт не может быть закрыт, если вызов DataReceived все еще застревает в вызове ReadLine(). Используйте BeginInvoke() вместо Invoke(), тем самым избегая тупиковой ситуации.

+0

Удивительное объяснение ...... – Vikky

+0

Я получаю вашу мысль, поэтому я не «действительно» понимаю ту часть, где RTB сохраняет текстовый буфер. Каждая минута = Очистить RTB> ReadExisting> Очистить> ReadExisting .. Я думал об этом из-за загрузки строки + размещения нужной строки. Не 'rtb.clear()' удаляет нагрузку rtb? – AdorableVB

+0

Несомненно, это должно помочь. Выбор 60 секунд был предположением, видимо, вам нужно меньше. Если текст прокручивается так быстро, что человек просто не может его прочитать, тогда просто нет смысла ставить его в RTB вообще. Anyhoo, исправьте реальную проблему. –

Смежные вопросы