S
Steven Spencer \(Spinalogic\)
Hey everyone, just converted a class from .net 1.1 to .net 2.0 and the
compiler has warned me of some deprecated usage of functions . Namely
thread.suspend and thread.resume.
My class was quite clean and the logic was sound (ie it worked). Now I was
considering writing the main loop to grab a semaphore whilst executing and
then play a file, however, I wish to have no limit on the number of sounds
that can be queued up by the player, so I can't use a semaphore as I cannot
know how many sounds can enqueue at any one time, and I CANNOT have the main
thread block in its call to "playsound" as would happen if I attempted to
"release" whilst the semaphore was already held.
I was considering using a monitor but then I run into the double check
problem, I need to check the monitor is released at just the right time and
all sorts of issues happen.
I suppose if someone could point me in the right direction for a good
technique to use. Essentially the class needs to return from playsound
immediately after enqueuing the file name. The main thread should wake up
any time that a sound is added to the queue, dequeue the sound and then play
it. Order and Timing are important (ie sounds must be played in the order
they are received, and all sounds in the queue MUST be played without a
delay (ie, Attention, "name", "Message" would be a common usage of the
function). I just can't think of a construct that would work efficiently.
And I'm certainly not asking people to write code for me, but if you can
point in the right direction I'd really appreciate it.
My CURRENT class is listed below.
Public Class AsyncSounds
Implements IDisposable
Private PlayQueue As System.Collections.Queue
Private SoundThread As System.Threading.Thread
Private Exiting As Boolean = False
Public Sub New()
PlayQueue = New System.Collections.Queue
SoundThread = New System.Threading.Thread(AddressOf PlayThread)
SoundThread.Name = "Sound Playing Thread"
SoundThread.Start()
Console.WriteLine("Sound Thread: Starting the Sound Play Thread")
End Sub
Public Sub PlaySound(ByVal SoundFile As String)
SyncLock (PlayQueue)
PlayQueue.Enqueue(SoundFile)
End SyncLock
Console.WriteLine("Main Thread: Added sound to queue.")
If SoundThread.ThreadState = Threading.ThreadState.Suspended Then
SoundThread.Resume() ''If the player is asleep, wake it up.
End If
End Sub
Private Sub PlayThread()
Dim Count As Integer = 0
Dim SoundFile As String = String.Empty
Do
If Exiting Then
Console.WriteLine("Sound Thread: Terminating")
Exit Sub
End If
SyncLock (PlayQueue)
Count = PlayQueue.Count
End SyncLock
If Count > 0 Then
SyncLock (PlayQueue)
SoundFile = CType(PlayQueue.Dequeue, String)
End SyncLock
Console.WriteLine("Sound Thread: Playing Sound. Count = " &
Count.ToString)
SoundClass.PlaySoundFile(SoundFile, True)
Else
Console.WriteLine("Sound Thread: Suspending")
System.Threading.Thread.CurrentThread.Suspend()
End If
Loop
End Sub
Public Sub Dispose() Implements System.IDisposable.Dispose
If Not Exiting Then
Exiting = True
If SoundThread.ThreadState <> Threading.ThreadState.Running Then
SoundThread.Resume()
SoundThread.Join()
GC.SuppressFinalize(Me)
End If
End Sub
End Class
compiler has warned me of some deprecated usage of functions . Namely
thread.suspend and thread.resume.
My class was quite clean and the logic was sound (ie it worked). Now I was
considering writing the main loop to grab a semaphore whilst executing and
then play a file, however, I wish to have no limit on the number of sounds
that can be queued up by the player, so I can't use a semaphore as I cannot
know how many sounds can enqueue at any one time, and I CANNOT have the main
thread block in its call to "playsound" as would happen if I attempted to
"release" whilst the semaphore was already held.
I was considering using a monitor but then I run into the double check
problem, I need to check the monitor is released at just the right time and
all sorts of issues happen.
I suppose if someone could point me in the right direction for a good
technique to use. Essentially the class needs to return from playsound
immediately after enqueuing the file name. The main thread should wake up
any time that a sound is added to the queue, dequeue the sound and then play
it. Order and Timing are important (ie sounds must be played in the order
they are received, and all sounds in the queue MUST be played without a
delay (ie, Attention, "name", "Message" would be a common usage of the
function). I just can't think of a construct that would work efficiently.
And I'm certainly not asking people to write code for me, but if you can
point in the right direction I'd really appreciate it.
My CURRENT class is listed below.
Public Class AsyncSounds
Implements IDisposable
Private PlayQueue As System.Collections.Queue
Private SoundThread As System.Threading.Thread
Private Exiting As Boolean = False
Public Sub New()
PlayQueue = New System.Collections.Queue
SoundThread = New System.Threading.Thread(AddressOf PlayThread)
SoundThread.Name = "Sound Playing Thread"
SoundThread.Start()
Console.WriteLine("Sound Thread: Starting the Sound Play Thread")
End Sub
Public Sub PlaySound(ByVal SoundFile As String)
SyncLock (PlayQueue)
PlayQueue.Enqueue(SoundFile)
End SyncLock
Console.WriteLine("Main Thread: Added sound to queue.")
If SoundThread.ThreadState = Threading.ThreadState.Suspended Then
SoundThread.Resume() ''If the player is asleep, wake it up.
End If
End Sub
Private Sub PlayThread()
Dim Count As Integer = 0
Dim SoundFile As String = String.Empty
Do
If Exiting Then
Console.WriteLine("Sound Thread: Terminating")
Exit Sub
End If
SyncLock (PlayQueue)
Count = PlayQueue.Count
End SyncLock
If Count > 0 Then
SyncLock (PlayQueue)
SoundFile = CType(PlayQueue.Dequeue, String)
End SyncLock
Console.WriteLine("Sound Thread: Playing Sound. Count = " &
Count.ToString)
SoundClass.PlaySoundFile(SoundFile, True)
Else
Console.WriteLine("Sound Thread: Suspending")
System.Threading.Thread.CurrentThread.Suspend()
End If
Loop
End Sub
Public Sub Dispose() Implements System.IDisposable.Dispose
If Not Exiting Then
Exiting = True
If SoundThread.ThreadState <> Threading.ThreadState.Running Then
SoundThread.Resume()
SoundThread.Join()
GC.SuppressFinalize(Me)
End If
End Sub
End Class