Re: Any multithreading CF libraries?
From: Chris Tacke, eMVP (ctacke_at_spamfree-opennetcf.org)
Date: 02/05/04
- Next message: Chuck : "Re: Pocket PC Form ZOrder SetTime"
- Previous message: Mobile Boy 36: "Re: HELP!! - How to add a simple custum control to the VS.NET toolbox?"
- In reply to: Jon Skeet [C# MVP]: "Re: Any multithreading CF libraries?"
- Next in thread: Jon Skeet [C# MVP]: "Re: Any multithreading CF libraries?"
- Reply: Jon Skeet [C# MVP]: "Re: Any multithreading CF libraries?"
- Messages sorted by: [ date ] [ thread ]
Date: Thu, 5 Feb 2004 10:32:49 -0500
Jon,
Thanks! I'll add it (with slight name changes) to the OpenNETCF SDF code,
which should be released in the next couple days. That'll get it in the
hands of many testers quickly.
--
Chris Tacke, eMVP
Co-Founder and Advisory Board Member
www.OpenNETCF.org
---
Windows CE Product Manager
Applied Data Systems
www.applieddata.net
"Jon Skeet [C# MVP]" <skeet@pobox.com> wrote in message
news:MPG.1a8c3d68fd39c98a98a07c@msnews.microsoft.com...
> Chris Tacke, eMVP <ctacke@spamfree-opennetcf.org> wrote:
> > I've not seen one, but I'd love to add one to the OpenNETCF libraries
and
> > would gladly help develop and test it.
>
> Righto, well, here's a start which I've run a few tests on, and seems
> to work. Apologies for the formatting - I don't keep my code in VS.NET
> to 72 columns, which is what I use to post.
>
>
> Sample usage is something like:
>
> FullMonitor monitor = new FullMonitor();
>
> monitor.Enter();
> try
> {
> // Do some stuff, possibly including monitor.Pulse etc
> }
> finally
> {
> monitor.Exit();
> }
>
>
>
>
> using System;
> using System.Threading;
>
> namespace Whatever
> {
> /// <summary>
> /// Fuller Monitor implementation than CF.NET supplies.
> /// </summary>
> public sealed class FullMonitor
> {
> /// <summary>
> /// The owner of the monitor, or null if it's not owned
> /// by any thread.
> /// </summary>
> Thread currentOwner=null;
>
> /// <summary>
> /// Number of levels of locking (0 for an unowned
> /// monitor, 1 after a single call to Enter, etc).
> /// </summary>
> int lockCount=0;
>
> /// <summary>
> /// Object to be used as a monitor for state changing.
> /// </summary>
> object stateLock = new object();
>
> /// <summary>
> /// AutoResetEvent used to implement Wait/Pulse/PulseAll.
> /// Initially not signalled, so that a call to Wait will
> /// block until the first pulse.
> /// </summary>
> AutoResetEvent waitPulseEvent = new AutoResetEvent(false);
>
> /// <summary>
> /// Number of threads waiting on this monitor.
> /// </summary>
> int waitCounter=0;
>
> /// <summary>
> /// Event used for Enter/Exit. Initially signalled
> /// to allow the first thread to come in.
> /// </summary>
> AutoResetEvent enterExitEvent = new AutoResetEvent(true);
>
> /// <summary>
> /// Creates a new monitor, not owned by any thread.
> /// </summary>
> public FullMonitor()
> {
> }
>
> /// <summary>
> /// Enters the monitor (locks it), blocking until the
> /// lock is held. If the monitor is already held by the current thread,
> /// its lock count is incremented.
> /// </summary>
> public void Enter()
> {
> Thread currentThread = Thread.CurrentThread;
> while (true)
> {
> enterExitEvent.WaitOne();
> lock (stateLock)
> {
> if (currentOwner==null)
> {
> currentOwner=currentThread;
> lockCount=1;
> enterExitEvent.Reset();
> return;
> }
> else if (currentOwner==currentThread)
> {
> lockCount++;
> return;
> }
> }
> }
> }
>
> /// <summary>
> /// Attempts to enter the monitor (locking it) but does not block
> /// if the monitor is already owned.
> /// </summary>
> /// <returns>Whether or not the current thread now owns the monitor.
> /// </returns>
> public bool TryEnter()
> {
> lock (stateLock)
> {
> if (currentOwner==null)
> {
> currentOwner=Thread.CurrentThread;
> lockCount=1;
> enterExitEvent.Reset();
> return true;
> }
> else if (currentOwner==Thread.CurrentThread)
> {
> lockCount++;
> return true;
> }
> return false;
> }
> }
>
> /// <summary>
> /// Releases a level of locking, unlocking the monitor itself
> /// if the lock count becomes 0.
> /// </summary>
> /// <exception cref="SynchronizationLockException"
> /// <exception cref="SynchronizationLockException">If the current
> /// thread does not own the monitor.</exception>
> public void Exit()
> {
> lock (stateLock)
> {
> if (currentOwner != Thread.CurrentThread)
> {
> throw new
> SynchronizationLockException
> ("Cannot Exit a monitor owned by a different thread.");
> }
> lockCount--;
> if (lockCount==0)
> {
> currentOwner=null;
> enterExitEvent.Set();
> }
> }
> }
>
> /// <summary>
> /// Pulses the monitor once - a single waiting thread will be released
> /// and continue its execution after the current thread has exited the
> /// monitor. Unlike Pulse on the normal framework, no guarantee is
> /// made about which thread is woken.
> /// </summary>
> /// <exception cref="SynchronizationLockException">If the
> /// current thread does not own the monitor.</exception>
> public void Pulse()
> {
> lock (stateLock)
> {
> if (currentOwner != Thread.CurrentThread)
> {
> throw new
> SynchronizationLockException
> ("Cannot Exit a monitor owned by a different thread.");
> }
> // Don't bother setting the event if no-one's waiting - we'd only end
> // up having to reset the event manually.
> if (waitCounter==0)
> {
> return;
> }
> waitPulseEvent.Set();
> waitCounter--;
> }
> }
>
> /// <summary>
> /// Pulses the monitor such that all waiting threads are woken up.
> /// All threads will then try to regain the lock on this monitor.
> /// No order for regaining the lock is specified.
> /// </summary>
> /// <exception cref="SynchronizationLockException">If the current
> /// thread does not own the monitor.</exception>
> public void PulseAll()
> {
> lock (stateLock)
> {
> if (currentOwner != Thread.CurrentThread)
> {
> throw new
> SynchronizationLockException
> ("Cannot Exit a monitor owned by a different thread.");
> }
> for (int i=0; i < waitCounter; i++)
> {
> waitPulseEvent.Set();
> }
> waitCounter=0;
> }
> }
>
> /// <summary>
> /// Relinquishes the lock on this monitor (whatever the lock count is)
> /// and waits for the monitor to be pulsed. After the monitor has been
> /// pulsed, the thread blocks again until it has regained the lock (at
> /// which point it will have the same lock count as it had before), and
> /// then the method returns.
> /// </summary>
> public void Wait()
> {
> int oldLockCount;
> lock (stateLock)
> {
> if (currentOwner != Thread.CurrentThread)
> {
> throw new
> SynchronizationLockException
> ("Cannot Exit a monitor owned by a different thread.");
> }
> oldLockCount = lockCount;
> // Make Exit() set the enterExitEvent
> lockCount=1;
> Exit();
> waitCounter++;
> }
> waitPulseEvent.WaitOne();
> Enter();
> // By now we own the lock again
> lock (stateLock)
> {
> lockCount=oldLockCount;
> }
> }
> }
> }
>
>
> using System;
>
> namespace Whatever
> {
> /// <summary>
> /// Exception thrown by FullMonitor when threading rules
> /// are violated (usually due to an operation being
> /// invoked on a monitor not owned by the current thread).
> /// </summary>
> public class SynchronizationLockException : Exception
> {
> public SynchronizationLockException(string message) :
> base(message)
> {
> }
> }
> }
>
> --
> Jon Skeet - <skeet@pobox.com>
> http://www.pobox.com/~skeet
> If replying to the group, please do not mail me too
- Next message: Chuck : "Re: Pocket PC Form ZOrder SetTime"
- Previous message: Mobile Boy 36: "Re: HELP!! - How to add a simple custum control to the VS.NET toolbox?"
- In reply to: Jon Skeet [C# MVP]: "Re: Any multithreading CF libraries?"
- Next in thread: Jon Skeet [C# MVP]: "Re: Any multithreading CF libraries?"
- Reply: Jon Skeet [C# MVP]: "Re: Any multithreading CF libraries?"
- Messages sorted by: [ date ] [ thread ]
Relevant Pages
|