Results 1 to 4 of 4

Thread: [RESOLVED] Alternative to mutex that doesn't get abandoned

  1. #1

    Thread Starter
    Hyperactive Member
    Join Date
    Apr 2007
    Location
    cobwebbed to PC
    Posts
    311

    Resolved [RESOLVED] Alternative to mutex that doesn't get abandoned

    Hi folks,

    I was trying to use a mutex to solve an issue I am having but it doesn't work as by necessity the function that acquires the mutex is not always the one that releases it.

    The issue is that I have a function that manages access to a serial port. The data sent over the port is commands to an external device. Some of the commands take some time to execute on the device. This means that the port should not send any new commands until that time is elapsed, thus I added a timer and a boolean "busy" flag.

    But testing a boolean doesn't allow for a time-out (at least not without introducing another timer). So I changed this to using a mutex with Mutex.WaitOne().

    However, I get the exception "Object synchronization method was called from an unsynchronized block of code" on attempting to release the mutex from the timer handler. I thought maybe it was because the mutex is abandoned because the function that acquired the mutex does so before the timer starts and subsequently ends?

    Is there another way I can solve this?

    (SendSomeData() is always called from the GUI thread, I currently have no other threads in the program)

    VB Code:
    1. Imports System.Timers
    2. Imports System.Threading
    3.  
    4. Public Class SerialWrapper 'Kellogs in da hood!
    5.  
    6.     Private _busy As Mutex = New Mutex()
    7.     Private ExecutionTimer As SystemTimers.Timer = New System.timers.Timer()
    8.  
    9.     Public Sub New()
    10.         AddHandler ExecutionTimer.Elapsed, AddressOf OnExecutionComplete
    11.     End Sub
    12.  
    13.     Public Sub SendSomeData(data() As Byte, executionTime As Double) As Boolean
    14.         If _busy.WaitOne(1000) = False Then
    15.             Throw New TimeoutException("Too busy")
    16.         End If
    17.  
    18.         ' Manage the serial port here...
    19.  
    20.         If executionTime > 0 Then
    21.             ExecutionTimer.Interval = executionTime
    22.             ExecutionTimer.Start()
    23.         Else
    24.             _busy.ReleaseMutex()
    25.         End If
    26.     End Function
    27.  
    28.     Private Sub OnExecutionComplete(Source As Object, e As ElapsedEventArgs)
    29.         _busy.ReleaseMutex()
    30.         ExecutionTimer.Stop()
    31.     End sub
    32. End Class

    I added Console output lines to show the sequence of mutex acquisition and release which resulted in:

    Code:
    Acquiring mutex ' SendSomeData() called
    Mutex acquired
    Starting timer  'SendSomeData() finishes - maybe mutex is abandoned, thus allowing...
    Acquiring mutex 'SendSomeData() called a second time, before execution time is finished!
    Mutex Acquired
    Releasing mutex in timer 'Timer from first call finishes and releases second call mutex maybe
    Releasing mutex normally 'Second call finishes - mutex was already released though...
    Acquiring mutex 'SendSomeData() called a third time
    Mutex acquired  
    
    'Exception attempting to release mutex from timer occurs here
    Ta, T
    Last edited by wolf99; Oct 2nd, 2015 at 08:09 AM.
    Thanks

  2. #2
    You don't want to know.
    Join Date
    Aug 2010
    Posts
    4,578

    Re: Alternative to mutex that doesn't get abandoned

    Mutexes are really meant for cross-process communication, not cross-thread communication. You use them when your application and some other application interact but need a way to tell each other when some shared resource is blocked. In fact, Mutexes have thread affinity, not process affinity. That means you can only work with a Mutex from the thread that created it, just like controls. In your code, you're trying to use a Mutex for cross-thread synchronization. That's doomed to fail without additional thread marshalling.

    (Worth knowing: System.Timers.Timer doesn't guarantee it raises its events on the thread that created it. Only System.Windows.Forms.Timer makes that guarantee, and even then it's only if it's created on the UI thread.)

    What you really want is one of the WaitHandle classes, like ManualResetEvent. These are intended for cross-thread synchronization, and behave more or less like a waitable thread-safe Boolean.
    This answer is wrong. You should be using TableAdapter and Dictionaries instead.

  3. #3

    Thread Starter
    Hyperactive Member
    Join Date
    Apr 2007
    Location
    cobwebbed to PC
    Posts
    311

    Re: Alternative to mutex that doesn't get abandoned

    Thanks Sitten Spyne that works
    Thanks

  4. #4
    Super Moderator Shaggy Hiker's Avatar
    Join Date
    Aug 2002
    Location
    Idaho
    Posts
    40,102

    Re: [RESOLVED] Alternative to mutex that doesn't get abandoned

    Why don't you have a Queue set up. SendSomeData looks at the flag, and if it is set, it just pushes the data to the queue. When OnExecutionComplete fires, if there is anything in the Queue it sends that. In other words, decouple the processes. The main program is just spitting out data to be sent at whatever pace it wants to. A different system is taking those in, sending what it can and queuing up the rest to be sent when it gets a chance. That second system would be able to keep running as long as there is something in the Queue to be sent, and goes dormant once the Queue is empty.
    My usual boring signature: Nothing

Tags for this Thread

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  



Click Here to Expand Forum to Full Width