ManagementOperationWatcher.cs source code in C# .NET

Source code for the .NET framework in C#

                        

Code:

/ 4.0 / 4.0 / untmp / DEVDIV_TFS / Dev10 / Releases / RTMRel / ndp / fx / src / Wmi / managed / System / Management / ManagementOperationWatcher.cs / 1305376 / ManagementOperationWatcher.cs

                            using System; 
using System.Collections;
using System.Diagnostics;
using System.Threading;
using WbemClient_v1; 

namespace System.Management 
{ 

    ///  
    /// Represents the method that will handle the  event.
    /// 
    public delegate void ObjectReadyEventHandler(object sender, ObjectReadyEventArgs e);
 
    /// 
    /// Represents the method that will handle the  event. 
    ///  
    public delegate void CompletedEventHandler (object sender, CompletedEventArgs e);
 
    /// 
    /// Represents the method that will handle the  event.
    /// 
    public delegate void ProgressEventHandler (object sender, ProgressEventArgs e); 

    ///  
    /// Represents the method that will handle the  event. 
    /// 
    public delegate void ObjectPutEventHandler(object sender, ObjectPutEventArgs e); 

    /// 
    ///    Used to manage asynchronous operations and handle management information and events received asynchronously.
    ///  
    /// 
    ///    using System; 
    /// using System.Management; 
    ///
    /// // This sample demonstrates how to read a ManagementObject asychronously 
    /// // using the ManagementOperationObserver object.
    ///
    /// class Sample_ManagementOperationObserver {
    ///     public static int Main(string[] args) { 
    ///
    ///         //Set up a handler for the asynchronous callback 
    ///         ManagementOperationObserver observer = new ManagementOperationObserver(); 
    ///         MyHandler completionHandler = new MyHandler();
    ///         observer.Completed += new CompletedEventHandler(completionHandler.Done); 
    ///
    ///         //Invoke the asynchronous read of the object
    ///         ManagementObject disk = new ManagementObject("Win32_logicaldisk='C:'");
    ///         disk.Get(observer); 
    ///
    ///         //For the purpose of this sample, we keep the main 
    ///         // thread alive until the asynchronous operation is completed. 
    ///
    ///         while (!completionHandler.IsComplete) { 
    ///             System.Threading.Thread.Sleep(500);
    ///         }
    ///
    ///         Console.WriteLine("Size= " + disk["Size"] + " bytes."); 
    ///
    ///         return 0; 
    ///     } 
    ///
    ///     public class MyHandler 
    ///     {
    ///         private bool isComplete = false;
    ///
    ///         public void Done(object sender, CompletedEventArgs e) { 
    ///             isComplete = true;
    ///         } 
    /// 
    ///         public bool IsComplete {
    ///             get { 
    ///                 return isComplete;
    ///             }
    ///         }
    ///     } 
    /// }
    ///     
    ///    Imports System 
    /// Imports System.Management
    /// 
    /// ' This sample demonstrates how to read a ManagementObject asychronously
    /// ' using the ManagementOperationObserver object.
    ///
    /// Class Sample_ManagementOperationObserver 
    ///     Overloads Public Shared Function Main(args() As String) As Integer
    /// 
    ///         'Set up a handler for the asynchronous callback 
    ///         Dim observer As New ManagementOperationObserver()
    ///         Dim completionHandler As New MyHandler() 
    ///         AddHandler observer.Completed, AddressOf completionHandler.Done
    ///
    ///         ' Invoke the object read asynchronously
    ///         Dim disk As New ManagementObject("Win32_logicaldisk='C:'") 
    ///         disk.Get(observer)
    /// 
    ///         ' For the purpose of this sample, we keep the main 
    ///         ' thread alive until the asynchronous operation is finished.
    ///         While Not completionHandler.IsComplete Then 
    ///             System.Threading.Thread.Sleep(500)
    ///         End While
    ///
    ///         Console.WriteLine("Size = " + disk("Size").ToString() & " bytes") 
    ///
    ///         Return 0 
    ///     End Function 
    ///
    ///     Public Class MyHandler 
    ///         Private _isComplete As Boolean = False
    ///
    ///         Public Sub Done(sender As Object, e As CompletedEventArgs)
    ///             _isComplete = True 
    ///         End Sub 'Done
    /// 
    ///         Public ReadOnly Property IsComplete() As Boolean 
    ///             Get
    ///                 Return _isComplete 
    ///             End Get
    ///         End Property
    ///     End Class
    /// End Class 
    ///    
    ///  
    public class ManagementOperationObserver 
    {
        private Hashtable m_sinkCollection; 
        private WmiDelegateInvoker delegateInvoker;

        /// 
        ///     Occurs when a new object is available. 
        /// 
        public event ObjectReadyEventHandler        ObjectReady; 
 
        /// 
        ///     Occurs when an operation has completed. 
        /// 
        public event CompletedEventHandler          Completed;

        ///  
        ///     Occurs to indicate the progress of an ongoing operation.
        ///  
        public event ProgressEventHandler           Progress; 

        ///  
        ///     Occurs when an object has been successfully committed.
        /// 
        public event ObjectPutEventHandler          ObjectPut;
 
        /// 
        /// Initializes a new instance of the  class. This is the default constructor. 
        ///  
        public ManagementOperationObserver ()
        { 
            // We make our sink collection synchronized
            m_sinkCollection = new Hashtable ();
            delegateInvoker = new WmiDelegateInvoker (this);
        } 

        ///  
        ///     Cancels all outstanding operations. 
        /// 
        public void Cancel () 
        {
            // Cancel all the sinks we have - make a copy to avoid things
            // changing under our feet
            Hashtable copiedSinkTable =  new Hashtable (); 

            lock (m_sinkCollection) 
            { 
                //
                IDictionaryEnumerator sinkEnum = m_sinkCollection.GetEnumerator(); 

                try
                {
                    sinkEnum.Reset (); 

                    while (sinkEnum.MoveNext ()) 
                    { 
                        DictionaryEntry entry = (DictionaryEntry) sinkEnum.Current;
                        copiedSinkTable.Add (entry.Key, entry.Value); 
                    }
                }
                catch
                { 
                }
            } 
 
            // Now step through the copy and cancel everything
            try 
            {
                IDictionaryEnumerator copiedSinkEnum = copiedSinkTable.GetEnumerator();
                copiedSinkEnum.Reset ();
 
                while (copiedSinkEnum.MoveNext ())
                { 
                    DictionaryEntry entry = (DictionaryEntry) copiedSinkEnum.Current; 
                    WmiEventSink eventSink = (WmiEventSink) entry.Value;
 
                    try
                    {
                        eventSink.Cancel ();
                    } 
                    catch
                    { 
                    } 
                }
            } 
            catch
            {
            }
        } 

        internal WmiEventSink GetNewSink ( 
            ManagementScope scope, 
            object context)
        { 
            try
            {
                WmiEventSink eventSink = WmiEventSink.GetWmiEventSink(this, context, scope, null, null);
 
                // Add it to our collection
                lock (m_sinkCollection) 
                { 
                    m_sinkCollection.Add (eventSink.GetHashCode(), eventSink);
                } 

                return eventSink;
            }
            catch 
            {
                return null; 
            } 
        }
 
        internal bool HaveListenersForProgress
        {
            get
            { 
                bool result = false;
 
                try 
                {
                    if (Progress != null) 
                        result = ((Progress.GetInvocationList ()).Length > 0);
                }
                catch
                { 
                }
 
                return result; 
            }
        } 
        internal WmiEventSink GetNewPutSink (
            ManagementScope scope,
            object context,
            string path, 
            string className)
        { 
            try 
            {
                WmiEventSink eventSink = WmiEventSink.GetWmiEventSink(this, context, scope, path, className); 

                // Add it to our collection
                lock (m_sinkCollection)
                { 
                    m_sinkCollection.Add (eventSink.GetHashCode(), eventSink);
                } 
 
                return eventSink;
            } 
            catch
            {
                return null;
            } 
        }
 
        internal WmiGetEventSink GetNewGetSink ( 
            ManagementScope scope,
            object context, 
            ManagementObject managementObject)
        {
            try
            { 
                WmiGetEventSink eventSink = WmiGetEventSink.GetWmiGetEventSink(this,
                    context, scope, managementObject); 
 
                // Add it to our collection
                lock (m_sinkCollection) 
                {
                    m_sinkCollection.Add (eventSink.GetHashCode(), eventSink);
                }
 
                return eventSink;
            } 
            catch 
            {
                return null; 
            }
        }

        internal void RemoveSink (WmiEventSink eventSink) 
        {
            try 
            { 
                lock (m_sinkCollection)
                { 
                    m_sinkCollection.Remove (eventSink.GetHashCode ());
                }

                // Release the stub as we are now disconnected 
                eventSink.ReleaseStub ();
            } 
            catch 
            {
            } 
        }

        /// 
        /// Fires the ObjectReady event to whomsoever is listening 
        /// 
        ///   
        internal void FireObjectReady (ObjectReadyEventArgs args) 
        {
            try 
            {
                delegateInvoker.FireEventToDelegates (ObjectReady, args);
            }
            catch 
            {
            } 
        } 

        internal void FireCompleted (CompletedEventArgs args) 
        {
            try
            {
                delegateInvoker.FireEventToDelegates (Completed, args); 
            }
            catch 
            { 
            }
        } 

        internal void FireProgress (ProgressEventArgs args)
        {
            try 
            {
                delegateInvoker.FireEventToDelegates (Progress, args); 
            } 
            catch
            { 
            }
        }

        internal void FireObjectPut (ObjectPutEventArgs args) 
        {
            try 
            { 
                delegateInvoker.FireEventToDelegates (ObjectPut, args);
            } 
            catch
            {
            }
        } 
    }
 
    internal class WmiEventState 
    {
        private Delegate d; 
        private ManagementEventArgs args;
        private AutoResetEvent h;

        internal WmiEventState (Delegate d, ManagementEventArgs args, AutoResetEvent h) 
        {
            this.d = d; 
            this.args = args; 
            this.h = h;
        } 

        public Delegate Delegate
        {
            get { return d; } 
        }
 
        public ManagementEventArgs Args 
        {
            get { return args; } 
        }

        public AutoResetEvent AutoResetEvent
        { 
            get { return h; }
        } 
    } 

    ///  
    /// This class handles the posting of events to delegates. For each event
    /// it queues a set of requests (one per target delegate) to the thread pool
    /// to handle the event. It ensures that no single delegate can throw
    /// an exception that prevents the event from reaching any other delegates. 
    /// It also ensures that the sender does not signal the processing of the
    /// WMI event as "done" until all target delegates have signalled that they are 
    /// done. 
    /// 
    internal class WmiDelegateInvoker 
    {
        internal object sender;

        internal WmiDelegateInvoker (object sender) 
        {
            this.sender = sender; 
        } 

        ///  
        /// Custom handler for firing a WMI event to a list of delegates. We use
        /// the process thread pool to handle the firing.
        /// 
        /// The MulticastDelegate representing the collection 
        /// of targets for the event
        /// The accompanying event arguments 
        internal void FireEventToDelegates (MulticastDelegate md, ManagementEventArgs args) 
        {
            try 
            {
                if (null != md)
                {
#if USEPOOL 
                    Delegate[] delegateList = md.GetInvocationList ();
 
                    if (null != delegateList) 
                    {
                        int numDelegates = delegateList.Length; 
                        AutoResetEvent[] waitHandles = new AutoResetEvent [numDelegates];

                        /*
                         * For each target delegate, queue a request to the 
                         * thread pool to handle the POST. We pass as state the
                         *  1) Target delegate 
                         *  2) Event args 
                         *  3) AutoResetEvent that the thread should signal to
                         *     indicate that it is done. 
                         */
                        for (int i = 0; i < numDelegates; i++)
                        {
                            waitHandles [i] = new AutoResetEvent (false); 
                            ThreadPool.QueueUserWorkItem (
                                    new WaitCallback (this.FireEventToDelegate), 
                                    new WmiEventState (delegateList[i], args, waitHandles[i])); 
                        }
 
                        /*
                         * We wait for all the delegates to signal that they are done.
                         * This is because if we return from the IWbemObjectSink callback
                         * before they are all done, it is possible that a delegate will 
                         * begin to process the next callback before the current callback
                         * processing is done. 
                         */ 
                        WaitHandle.WaitAll (waitHandles, 10000, true);
                        } 
                    }
#endif
                    foreach (Delegate d in md.GetInvocationList())
                    { 
                        try
                        { 
                            d.DynamicInvoke (new object [] {this.sender, args}); 
                        }
                        catch 
                        {
                        }
                    }
                } 
            }
            catch 
            { 
            }
        } 

#if USE_POOL
        /// 
        /// This is the WaitCallback for firing an event from the thread pool 
        /// 
        /// Represents a WmiEventState object 
        internal void FireEventToDelegate (object state) 
        {
            if (state is WmiEventState) 
            {
                WmiEventState oState = (WmiEventState) state;

                try { 
                    oState.Delegate.DynamicInvoke (new object [] {this.sender, oState.Args});
                } 
                catch 
                {
                } 
                finally {
                    // Signal that we are done
                    oState.AutoResetEvent.Set();
                } 
            }
        } 
#endif 
    }
 
}

// File provided for Reference Use Only by Microsoft Corporation (c) 2007.
// Copyright (c) Microsoft Corporation. All rights reserved.


                        

Link Menu

Network programming in C#, Network Programming in VB.NET, Network Programming in .NET
This book is available now!
Buy at Amazon US or
Buy at Amazon UK