deadlock

Collapse
X
 
  • Time
  • Show
Clear All
new posts
  • manem78
    New Member
    • May 2007
    • 4

    deadlock

    Hi!
    Can someone explain me why I always end up with deadlock in the next piece of code. Deadlock occurs when I hit Button1 couple of times. Thanks!!!
    [code=vbnet]
    Public Module Module_Tags
    'Tag
    Public Class Tags
    Public Shared objLock As New Object
    Public Tag_Address As Integer
    End Class

    'Memory Integer
    Public Class MI_Tag
    Inherits Tags
    Public Tag_Value As Short
    Public To_Output As Short
    Public Sub New()
    MyBase.New()
    End Sub

    Public Shared Function Read_MemInteger s(ByVal Start_Address As Integer, ByVal Length As Integer, ByRef MemIntegers() As Short) As Boolean
    Dim No_Error As Boolean
    Try
    SyncLock objLock
    No_Error = mComDriver.Read _MemIntegers(St art_Address, Length, MemIntegers, 0)
    End SyncLock
    Return No_Error
    Catch ex As Exception
    Return False
    End Try
    End Function

    Public Sub New(ByVal Address As Integer, ByVal Init As Short)
    Tag_Address = Address
    Tag_Value = Init
    End Sub

    Public Function To_Device() As Boolean
    Dim No_Error As Boolean
    Try
    Dim MI() As Short = {To_Output}
    SyncLock objLock
    No_Error = mComDriver.Writ e_MemIntegers(T ag_Address, 1, MI, 0)
    End SyncLock
    Return No_Error
    Catch ex As Exception
    Return False
    End Try
    End Function
    End Class
    End Module



    Public Class Main_Window
    Public WithEvents Timer As New Timers.Timer
    Public ExampleTag As New MI_Tag(20, 0)

    Private Sub Main_Window_Loa d(ByVal sender As Object, ByVal e As System.EventArg s) Handles Me.Load
    Timer.Interval = 1000
    Timer.Start()
    End Sub

    Public Sub Timer_Tick(ByVa l sender As Object, ByVal e As System.Timers.E lapsedEventArgs ) Handles Timer.Elapsed
    Dim i() As Short
    Dim a As Boolean
    a = MI_Tag.Read_Mem Integers(0, 255, i)
    End Sub

    Private Sub Button1_Click(B yVal sender As System.Object, ByVal e As System.EventArg s) Handles Button1.Click
    ExampleTag.To_O utput = 5
    ExampleTag.To_D evice()
    End Sub

    [/code]
  • debasisdas
    Recognized Expert Expert
    • Dec 2006
    • 8119

    #2
    Hi
    manem
    Welcome to TSDN.

    You have reached the right place for knowledge shairing.

    Here you will find a vast resource of related topics and code.

    Feel free to post more doubts/questions in the forum.

    But before that give a try from your side and if possible try to post what/how you have approached to solve the problem.
    It will help Experts in the forum in solving/underestanding your problem in a better way.

    Comment

    • manem78
      New Member
      • May 2007
      • 4

      #3
      Hi debasisdas!
      I am writing SCADA program. mComDriver is a simple communication protocol driver for communication between PLC and PC. It comes with PLC, in this case Unitronics Vision 290. It has simple methods (mComDriver.Rea d_MemIntegers, mComDriver.writ e_MemIntegers,. ..) for reading and writing values from and to PLC. SCADA is reading values from PLC every 1 second (timer.interval = 1000) and has buttons for writing to PLC. The problem is that both procedures (reading and writing) use same control (mComDriver). Sometimes it happens that communication fails because reading interrupts writing and vice versa. It happens because, as I understood, the procedure for button click starts in new thread so both statements(read , write) can execute at the same time . In previous versions of VB (VB6..) this was not the case and there was no problem.
      So, that is why I used synclock statement. I tried to synchronize reading and writing but now I have deadlock problem. I don't understand why it happens because both procedures use the same lock object.
      I hope that this will give you a closer look to my problem.

      Comment

      • Plater
        Recognized Expert Expert
        • Apr 2007
        • 7872

        #4
        Hi, you should create some sort of basic mutexing system.
        Here's a possible solution:

        Declare a global boolean variable such as like AbleToREAD
        At the begining of where you WRITE (your button click?) set AbleToRead=Fals e
        At the END of where you write (after all the writing is done) set AbleToRead=True ;

        Now inside wherever you READ (your timer_tick?) do a condition check before you read with like:
        [code=vb]
        IF AbleToRead THEN
        'do your reading
        ELSE
        'do nothing
        ENDIF
        [/code]

        You could also do something similar, only in reverse, to make sure that the Writing doesn't occur while the timer_tick() is Reading.

        Comment

        • manem78
          New Member
          • May 2007
          • 4

          #5
          Hi Plater!
          That was the exactly the first idea that came up to me! I created PLC_Busy variable and control the synchronization with it. But the problem with that approach is when you hit the button to write and PLC is busy, program will simply skip over the procedure. Than I need to continue clicking the button until PLC become free and it is not certain that will ever happen.
          So, I actually need some simple synchronization that will exclude writing and reading and put them in a queue of order.
          I thought that SyncLock will do the work but I end up with deadlock which I can't explain.
          Perhaps the problem is because I am writing in VB.NET and PLC driver is old COM object. I don't know... :)

          Comment

          • manem78
            New Member
            • May 2007
            • 4

            #6
            Yuhuu!!!
            Is there anybody home...?!? :)
            I need help!!!

            Comment

            • Plater
              Recognized Expert Expert
              • Apr 2007
              • 7872

              #7
              So make some sort of queue-ing system?
              Have it continue to do the reads as long as there is not a WRITE waiting to happen, if so

              When you click your WRITE variables section, have it set a bool value to say "stop doing the reads" and then it waits for the READ section to set it's bit saying "done reading, device is free" at which point your WRITE section continues on and writes it's variables. When it's done writing it will change the first bool back so that the reading can continue.


              this shouldn't take a lot of effort.

              Comment

              Working...