Click here to Skip to main content
15,907,497 members
Please Sign up or sign in to vote.
0.00/5 (No votes)
See more:

I have an issue regarding stopping unresponsive function. I read many atricles on threading and background worker but unbale to find solution.

I am using 2015 and my application communicates with 3rd party IP device over TCP.

I am using function provided by device manufacturer. Unfortunately this function does not have error handling and does not throw exceptions it simply hangs if for any reason PLC does not respond. The execution itself stops at this point and even cancelling the thread does not work.
I tried try catch , do while timers etc , but no joy since thread has become unresponsive at this function.

Every now and then the device just stops communicating back towards my application and that makes the function that is performing the data capturing unresponsive.

How should I handle this?

It doesn't throw anything, it just stops responding. I think the problem is that sometimes my application loses connection with the that device.
When I then ask the device if it's ready for input it cannot return either true or false since the connection is gone so my application just waits for a response.

I also tried using a backgroundworker for my function.


What I have tried:

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
            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
                While axCZKEM1.SSR_GetGeneralLogData(iMachineNumber, sdwEnrollNumber, idwVerifyMode, idwInOutMode, idwYear, idwMonth, idwDay, idwHour, idwMinute, idwSecond, idwWorkcode)
                        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()
                                r("Datestamp") = Datestamp & " " & Timestamp
                                r("TimeS") = Timestamp
                                r("DateS") = Datestamp
                                If sdwEnrollNumber = "" Then
                                    r("MachineID") = sdwEnrollNumber
                                End If
                            Catch ex As Exception
                                Continue While
                            End Try
                        End If
                    Catch ex As Exception
                        Continue While
                    End Try
                End While
            Catch ex As Exception

            End Try
End Sub
Updated 1-Jun-18 1:14am
Jochen Arndt 31-May-18 7:10am    
If the execution is blocked within a function of a 3rd party DLL you can't do anything (besides asking the manufacturer to change that by adding for example a timeout value).

Otherwise you can (and should) use a worker thread which supports timeout and cancelling by an event.

Further help requires knowing how you call that function, what the function does, and - most important - how the function behaves. The latter should be part of the documentation.

If you the above information use the green 'Improve question' link to add it to your question.
CHill60 31-May-18 7:11am    
We can't see what you are seeing. Although you've described your problem we still have no idea what your code looks like, how you are connecting, etc etc etc.
Use the Improve Question link to post (just) the code that you are having the problem with

1 solution

Use a Timer in your app to provide a "unresponsive" detection, and start your function on a separate thread - a BackgroundWorker is a good choice as it automatically dies if it's "parent" thread ends for any reason (like your app ending).

When the timer detects the unresponsive function, you can Abort the thread which will kill it regardless. See here: c# - How to "kill" background worker completely? - Stack Overflow[^] - the code is in C#, but it's pretty obvious and online code converters can help you if you realy can't work it out: Code Converter C# to VB and VB to C# – Telerik[^]
Share this answer

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900