Member 10502967 Ответов: 1

Vb.net невосприимчивая функция


Привет

У меня есть проблема с остановкой невосприимчивой функции. Я прочитал много предсердий о потоковом и фоновом работнике, но не смог найти решение.

Я использую VB.net 2015 и мое приложение взаимодействует с 3-мя сторонними IP-устройствами по протоколу TCP.

Я использую функцию, предоставленную производителем устройства. К сожалению, эта функция не имеет обработки ошибок и не выбрасывает исключений, она просто зависает, если по какой-либо причине ПЛК не отвечает. Само выполнение останавливается в этот момент, и даже отмена потока не работает.
Я попробовал попробовать поймать , сделать таймеры while и т. д. , Но никакой радости, так как поток перестал отвечать на эту функцию.

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

Как я должен справиться с этим?

Он ничего не выбрасывает, просто перестает реагировать. Я думаю, что проблема заключается в том, что иногда мое приложение теряет связь с этим устройством.
Когда я затем спрашиваю устройство, готово ли оно к вводу, оно не может вернуть ни true, ни false, так как соединение пропало, поэтому мое приложение просто ждет ответа.

Я также попытался использовать backgroundworker для своей функции.

Спасибо,

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

Following is code is running under regular form under button click event.
It is not under background worker or not in separate thread.

Public Sub GetLogData(Optional ByVal DateSt As Date = Nothing, Optional ByVal IPAddress As String = "",Optional ByVal MachineDBName As String = "")

        ExecuteNonQuery("update realtimeattandance Set MergeData = Cast(Cast(TimeS  as varchar)+' '+Cast(Dates as Varchar)+' '+Cast(MachineID as Varchar) as nvarchar) Where Mergedata IS NULL")

        If bIsConnected2 = False Then
            GetDataMode = False
            MessageBox.Show("Connected (bIsConnected) Should be True")
            Exit Sub
        End If
                
        WaitDlg(sWaitDlgStatus.Show, "Get Data From " & IPAddress.ToString, "Wait")

        Dim sdwEnrollNumber As String = ""
        Dim idwVerifyMode As Integer
        Dim idwInOutMode As Integer
        Dim idwYear As Integer
        Dim idwMonth As Integer
        Dim idwDay As Integer
        Dim idwHour As Integer
        Dim idwMinute As Integer
        Dim idwSecond As Integer
        Dim idwWorkcode As Integer

        Cursor = Cursors.WaitCursor
        Ds = New DataSet
        Try
            If Ds.Tables.Contains("DataM") Then Ds.Tables("DataM").Clear()
            Dim Q As String
            Q = "Select * From realtimeattandance_Manual Where MachineID = -1"
            FillDataset(Ds, Q, "DataM")
        Catch ex As Exception

        End Try
        axCZKEM1.EnableDevice(iMachineNumber, False) 'disable the device
        Cursor = Cursors.WaitCursor

        ''''''''''' Below line is the reference to DLL provided by manufacturer. It reads data from device. And that creates the issue when we have connection problem with device. 
		''''''''''' During the data fetching, if connection gets bereak (before getting all data)then following line make application unresponsive.
		
        If axCZKEM1.ReadGeneralLogData(iMachineNumber) Then 'read all the attendance records to the memory
            'above line get records from the memory
            
			
			
			Try
                While axCZKEM1.SSR_GetGeneralLogData(iMachineNumber, sdwEnrollNumber, idwVerifyMode, idwInOutMode, idwYear, idwMonth, idwDay, idwHour, idwMinute, idwSecond, idwWorkcode)
                    Try
                        If sdwEnrollNumber = "ÿ" Or sdwEnrollNumber = "" Then
                            Continue While
                        End If

                        Dim Hour As String = idwHour.ToString()
                        If Hour.Length = 1 Then Hour = "0" & Hour

                        Dim Minute As String = idwMinute.ToString
                        If Minute.Length = 1 Then Minute = "0" & Minute

                        Dim Second As String = idwSecond.ToString()
                        If Second.Length = 1 Then Second = "0" & Second

                        Dim Timestamp As String = Hour & ":" & Minute & ":" & Second

                        Dim Year As String = idwYear.ToString()

                        Dim Month As String = idwMonth.ToString()
                        If Month.Length = 1 Then Month = "0" & Month

                        Dim Day As String = idwDay.ToString()
                        If Day.Length = 1 Then Day = "0" & Day

                        Dim Datestamp As String = Year & "-" & Month & "-" & Day

                        If Datestamp >= Format(DateSt, "yyyy-MM-dd").ToString Then
                            Dim r As DataRow
                            r = Ds.Tables("DataM").NewRow()
                            Try
                                r("Datestamp") = Datestamp & " " & Timestamp
                                r("TimeS") = Timestamp
                                r("DateS") = Datestamp
                                If sdwEnrollNumber = "" Then
                                Else
                                    r("MachineID") = sdwEnrollNumber
                                End If
                            Catch ex As Exception
                                Continue While
                            End Try
                            Ds.Tables("DataM").Rows.Add(r)
                        End If
                    Catch ex As Exception
                        Continue While
                    End Try
                End While
            Catch ex As Exception

            End Try
End Sub

Jochen Arndt

Если выполнение блокируется в функции сторонней библиотеки DLL, вы ничего не можете сделать (кроме как попросить производителя изменить это, добавив, например, значение таймаута).

В противном случае вы можете (и должны) использовать рабочий поток, который поддерживает тайм-аут и отмену события.

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

Если у вас есть вышеприведенная информация, используйте зеленую ссылку "улучшить вопрос", чтобы добавить ее к вашему вопросу.

CHill60

Мы не видим того, что видишь ты. Хотя вы описали свою проблему, мы все еще понятия не имеем, как выглядит ваш код, как вы подключаетесь и т. д.
Используйте ссылку улучшить вопрос, чтобы опубликовать (просто) код, с которым у вас возникли проблемы

1 Ответов

Рейтинг:
2

OriginalGriff

Используйте таймер в вашем приложении, чтобы обеспечить "невосприимчивое" обнаружение, и запустите свою функцию в отдельном потоке - BackgroundWorker-хороший выбор, так как он автоматически умирает, если его "Родительский" поток заканчивается по какой-либо причине (например, ваше приложение заканчивается).

Когда таймер обнаруживает невосприимчивую функцию, вы можете прервать поток, который все равно убьет его. Видеть здесь: c# - как полностью "убить" фонового рабочего? - переполнение стека[^] - код написан на C#, но это довольно очевидно, и онлайн-конвертеры кода могут помочь вам, если вы действительно не можете его понять: Преобразователь кода C# в VB и VB в C# – Telerik[^]