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:
Imports System.Timers
Imports System.Threading
Public Class SerialWrapper 'Kellogs in da hood!
Private _busy As Mutex = New Mutex()
Private ExecutionTimer As SystemTimers.Timer = New System.timers.Timer()
Public Sub New()
AddHandler ExecutionTimer.Elapsed, AddressOf OnExecutionComplete
End Sub
Public Sub SendSomeData(data() As Byte, executionTime As Double) As Boolean
If _busy.WaitOne(1000) = False Then
Throw New TimeoutException("Too busy")
End If
' Manage the serial port here...
If executionTime > 0 Then
ExecutionTimer.Interval = executionTime
ExecutionTimer.Start()
Else
_busy.ReleaseMutex()
End If
End Function
Private Sub OnExecutionComplete(Source As Object, e As ElapsedEventArgs)
_busy.ReleaseMutex()
ExecutionTimer.Stop()
End sub
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