Home | Contact Us | FAQ | Search & Site Map | Link to Us
Sign In | Join | Other 45 Sites in Network
HomeAnnouncementsFree MagazinesWhite PapersSubmit Content
Discussion GroupsASP.NETWindows FormsLanguages.NET FrameworkVisual Studio.NET
Articles.NET FrameworkASP.NETToolsWindows Forms
.NET DirectoryOpen Source ProjectsUser GroupsWeb Resources
Related Topics
Visual Basic 6SQL ServerMS AccessOther DB ProductsMS Server ProductsMore Topics ...

.NET Forum / .NET Framework / New Users / February 2007

Tip: Looking for answers? Try searching our database.

Thread Synchronisation

Thread view: 
Enable EMail Alerts  Start New Thread
Thread rating: 
Steven Spencer (Spinalogic) - 18 Feb 2007 03:07 GMT
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
Jon Skeet [C# MVP] - 18 Feb 2007 08:00 GMT
> 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
[quoted text clipped - 11 lines]
> problem, I need to check the monitor is released at just the right time and
> all sorts of issues happen.

It's not clear to me why you're suspending and resuming at all, but
Monitor.Wait/Pulse or Auto/ManualResetEvents are almost certainly the
best solution here.

See http://pobox.com/~skeet/csharp/threads/ for more information.

Signature

Jon Skeet - <skeet@pobox.com>
http://www.pobox.com/~skeet   Blog: http://www.msmvps.com/jon.skeet
If replying to the group, please do not mail me too

Steven Spencer (Spinalogic) - 18 Feb 2007 08:35 GMT
I need the sounds to be enqueued in an Asynchronous manner.

I need the sounds to PLAY in a synchronous manner (1 followed by the next,
as opposed to over the top of each other)

I want the thread to sleep/block so that I'm not using a busy wait algorithm
and hence being extremely inefficient.

>> 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
[quoted text clipped - 23 lines]
>
> See http://pobox.com/~skeet/csharp/threads/ for more information.
Jon Skeet [C# MVP] - 18 Feb 2007 12:56 GMT
> I need the sounds to be enqueued in an Asynchronous manner.
>
[quoted text clipped - 3 lines]
> I want the thread to sleep/block so that I'm not using a busy wait algorithm
> and hence being extremely inefficient.

Then Monitor.Wait/Pulse should be fine.

Signature

Jon Skeet - <skeet@pobox.com>
http://www.pobox.com/~skeet   Blog: http://www.msmvps.com/jon.skeet
If replying to the group, please do not mail me too

mangist@gmail.com - 23 Feb 2007 03:12 GMT
On Feb 18, 3:35 am, "Steven Spencer \(Spinalogic\)" <Spence-
Spinalo...@newsgroup.nospam> wrote:
> I need the sounds to be enqueued in an Asynchronous manner.
>
[quoted text clipped - 38 lines]
>
> - Show quoted text -

I would recommend using an AutoResetEvent to signal to the thread that
a sound has finished and to play the next one.

I.e. (In C# I apologize)

using System.Threading;

private Queue soundQueue = new Queue();

// This is our wait handle for signalling the thread
private AutoResetEvent waitHandle = new AutoResetEvent(false);

private bool running = false;

public void PlaySound(string soundFile) {
 lock (soundQueue) {
   soundQueue.Enqueue(soundFile)

   // Now you want to signal to the soundThread that a new sound was
added
   waitHandle.Set();
 }
}

public void New() {
 running = true;

 Thread soundThread = new Thread(new ThreadStart (PlayThread));
 soundThread.Start();
}

public void PlayThread() {

do {

 lock (soundQueue) {

   if (soundQueue.Count > 0) {

     // Play the sound....
   }
 }

} while (running && waitHandle.WaitOne());

}

public void StopThread() {
 running = false;

 // Signal the thread that we have changed the status of running
 waitHandle.Set();

}

There you have it, runs like a charm.  AutoResetEvents and
ManualResetEvents are the best way of signalling to another thread
that you want it to continue processing.  Waiting on a resetEvent will
block the thread until you signal (i.e. Set()) the wait handle.
Jon Skeet [C# MVP] - 25 Feb 2007 14:01 GMT
<snip>

> There you have it, runs like a charm.  AutoResetEvents and
> ManualResetEvents are the best way of signalling to another thread
> that you want it to continue processing.  Waiting on a resetEvent will
> block the thread until you signal (i.e. Set()) the wait handle.

In what way would you say they're better than using Monitor.Wait/Pulse?
There are certainly situations where they're more applicable,
particularly where you want to be able to wait on multiple handles, but
my "default choice" is usually to use monitors, which are "lighter
weight" than Manual/AutoResetEvents.

Signature

Jon Skeet - <skeet@pobox.com>
http://www.pobox.com/~skeet   Blog: http://www.msmvps.com/jon.skeet
If replying to the group, please do not mail me too


Free Magazines

Get these publications absolutely FREE for up to 12 months. There are no hidden fees and no obligation. Simply choose a title, complete the application form and submit it. Read more ...

Oracle MagazineNetwork ComputingComputer WorldBio-IT WorldeWeekInformation WeekInfosecurity
 
Sign In
Join
My Latest Posts
My Monitored Threads
My Blog
My Photo Gallery
My Profile
My Homepage

Start New Thread
Enable EMail Alerts
Rate this Thread



©2008 Advenet LLC   Privacy Policy - Terms of Use
This website includes both content owned or controlled by Advenet as well as content owned or controlled by third parties.