|
-
Oct 2nd, 2015, 08:03 AM
#1
Thread Starter
Hyperactive Member
[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:
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
Last edited by wolf99; Oct 2nd, 2015 at 08:09 AM.
Thanks 
-
Oct 2nd, 2015, 08:58 AM
#2
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.
-
Oct 2nd, 2015, 09:31 AM
#3
Thread Starter
Hyperactive Member
Re: Alternative to mutex that doesn't get abandoned
Thanks Sitten Spyne that works
Thanks 
-
Oct 2nd, 2015, 09:33 AM
#4
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
-
Forum Rules
|
Click Here to Expand Forum to Full Width
|