C#: Events

Simply put, an event is a notification that something happened to an object. In the case of a program, it can be the execution of different code when a certain event is triggered for instances of an object, without having to create separate object definitions. For example, let’s take on the task of programming a group of security motion detecting cameras in someone’s home. As part of our installations, each camera will perform different commands events occur. In this example we’ll define a camera object that has events when the camera is started, stopped or motion is detected. Instead of having to construct separate camera objects, we create three identical cameras and respond to the cameras’ events based upon the code we create to handle the events through the monitoring software. The sample camera class listed below:

using System;

namespace Events
{
    /// <summary>
    /// The arguments passed to the eventhandler when an event occurs.
    /// </summary>
    public class CameraEventArgs : EventArgs
    {
        //You can pass the EventArgs that you need to process in your handler
        public readonly string Name;
        public readonly string Command;

        public CameraEventArgs( string name, string command )
        {
            this.Name = name;
            this.Command = command;
        }
    }

    /// <summary>
    /// An enumeration of camera statuses
    /// </summary>
    public enum CameraStatus
    {
        Starting,
        Running,
        Stopping,
        Stopped
    }

    /// <summary>
    /// 
    /// </summary>
    class Camera
    {
        #region Fields
        private string name;
        private CameraStatus status;
        #endregion

        #region Properties
        /// <summary>
        /// The name of the camera
        /// </summary>
        public string Name
        {
            get
            {
                return name;
            }
        }
        /// <summary>
        /// The current status of the camera
        /// </summary>
        public CameraStatus Status
        {
            get
            {
                return status;
            }
        }
        #endregion

        #region Constructors
        public Camera( string name )
        {
            this.name = name;
            this.status = CameraStatus.Stopped;
        }
        #endregion

        #region Methods
        /// <summary>
        /// Start the camera
        /// </summary>
        /// <param name="command">The start command passed to the camera</param>
        /// <returns>A value identifying if the camera was successfully started.</returns>
        public bool Start( string command )
        {
            // We only want to start a camera if it is stopped; if it is already running we do not want a double start
            if ( status == CameraStatus.Stopped )
            {
                status = CameraStatus.Starting;
                // create the arguments to pass
                CameraEventArgs e = new CameraEventArgs ( this.Name, command );
                CameraStarted ( e );
                status = CameraStatus.Running;
                return true;
            }
            else
            {
                return false;
            }
        }

        /// <summary>
        /// Stop the camera
        /// </summary>
        /// <param name="command">The stop comand passed to the camera</param>
        /// <returns>A value identifying if the camera was successfully stopped.</returns>
        public bool Stop(string command)
        {
            // We only can stop a running camera
            if ( status == CameraStatus.Running )
            {
                status = CameraStatus.Stopping;
                // create the arguments to pass
                CameraEventArgs e = new CameraEventArgs ( this.Name, command );
                CameraStarted ( e );
                status = CameraStatus.Stopped;
                return true;
            }
            else
            {
                return false;
            }
        }

        /// <summary>
        /// Called when movement is detected by the camera
        /// </summary>
        public void MovementDetected()
        {
            // Something should only occur when movement is detected for a running camera
            if ( status == CameraStatus.Running )
            {
                // create the arguments to pass
                CameraEventArgs e = new CameraEventArgs ( this.Name, "" );
                MovementDetected ( e );
            }
        }

        /// <summary>
        /// Occurs when the camera is starting
        /// </summary>
        /// <param name="e">Camera event argument</param>
        protected void CameraStarted( CameraEventArgs e )
        {
            // Run the event assigned at camera start
            if ( OnCameraStart != null )
            {
                OnCameraStart ( e );
            }
        }

        /// <summary>
        /// Occurs when the camera is stopping
        /// </summary>
        /// <param name="e">Camera event argument</param>
        protected void CameraStoppeed( CameraEventArgs e )
        {
            // Run the event assigned at camera stop
            if ( OnCameraStop != null )
            {
                OnCameraStop ( e );
            }
        }

        /// <summary>
        /// Occurs when the camera detects motion
        /// </summary>
        /// <param name="e">Camera event argument</param>
        protected void MovementDetected( CameraEventArgs e )
        {
            if ( OnMovementDetected != null )
            {
                OnMovementDetected ( e );
            }
        }

        #endregion

        #region Delegates
        // A delegate is basically a pointer to an object
        public delegate void CameraErrorHandler( CameraEventArgs e );
        #endregion

        #region Events
        public event CameraErrorHandler OnCameraStart;
        public event CameraErrorHandler OnCameraStop;
        public event CameraErrorHandler OnMovementDetected;
        #endregion
    }
}

Once the cameras are deployed we can work with each camera independently and respond to the cameras events from the management program:

public partial class Form1 : Form
    {
        List<Camera> machines;

        public Form1()
        {
            InitializeComponent ();
            machines = new List<Camera> ();
            InitCamera ();
            dataGridView1.DataSource = machines;
        }

        /// <summary>
        /// Initialize the cameras for this implimentation
        /// </summary>
        protected void InitCamera()
        {
            Camera m;
            m = new Camera ( "Bedroom Camera" );
            //specify the events for the camera
            m.OnCameraStart += Camera1Started;
            m.OnCameraStop += CameraStopped;
            machines.Add ( m );

            m = new Camera ( "Kitchen Camera" );
            m.OnCameraStart += Camera1Started;
            m.OnCameraStop += CameraStopped;
            machines.Add ( m );

            m = new Camera ( "Hall Camera" );
            m.OnCameraStart += Camera2Started;
            m.OnCameraStop += CameraStopped;
            machines.Add ( m );
        }

        private void btnRefresh_Click( object sender, EventArgs e )
        {
            dataGridView1.DataSource = machines;
            dataGridView1.Refresh ();
        }

        private void btnStart_Click( object sender, EventArgs e )
        {
            machines[dataGridView1.CurrentRow.Index].Start ( "Start" );
        }

        private void btnStop_Click( object sender, EventArgs e )
        {
            machines[dataGridView1.CurrentRow.Index].Stop ( "Stop" );
        }

        /// <summary>
        /// A camera event
        /// </summary>
        /// <param name="e">Camera event arguments</param>
        protected void Camera1Started( CameraEventArgs e )
        {
            MessageBox.Show ( String.Format ( "{0} - {1}", e.Name, e.Command ),"Camera1" );
        }

        /// <summary>
        /// A camera event
        /// </summary>
        /// <param name="e">Camera event arguments</param>
        protected void Camera2Started( CameraEventArgs e )
        {
            MessageBox.Show ( String.Format ( "{0} - {1}", e.Name, e.Command ), "Camera2" );
        }

        /// <summary>
        /// A camera event
        /// </summary>
        /// <param name="e">Camera event arguments</param>
        protected void CameraStopped( CameraEventArgs e )
        {
            MessageBox.Show ( String.Format ( "{0} - {1}", e.Name, e.Command ), "Camera" );
        }


    }

This example is intended to be a simplified explanation of events and is not coded to be reflective of a fully developed application.



   

Some of my Favorite Quotes

A few great quotes that could be auto-rotated on a signature block. If there are any other great quotes I'd be interested in seeing them.

"The only difference between me and a madman is that I'm not mad." -- Salvador Dali (1904 - 1989)

"There's a fine line between genius and insanity. I have erased this line." -- Oscar Levant (1906 - 1972)

"Associate yourself with men of good quality if you esteem your own reputation. It is better be alone than in bad company." -- George Washington (1732-1799)

"Anyone who has never made a mistake has never tried anything new." -- Albert Einstein (1879 - 1955)

"He was so learned that he could name a horse in nine languages; so ignorant that he bought a cow to ride on." -- Benjamin Franklin (1706-1790)

"Don't find a fault. Find a remedy." -- Henry Ford (1863-1947)

"Few people are capable of expressing with equanimity opinions which differ from the prejudices of their social environment. Most people are even incapable of forming such opinions." -- Albert Einstein (1879 - 1955)

"Only two things are infinite, the universe and human stupidity, and I'm not sure about the former." -- Albert Einstein (1879 - 1955)

"Have no fear of perfection - you'll never reach it." -- Salvador Dali (1904 - 1989)

"Wars have never hurt anybody except the people who die." -- Salvador Dali (1904 - 1989)

"Many go fishing all their lives without knowing that it is not fish they are after." -- Henry David Thoreau (1817-1862)

"The quality of an individual is reflected in the standards they set for themselves." -- Ray Kroc (1902-1984)

"Blessed is he that expects nothing, for he shall never be disappointed." -- Benjamin Franklin (1706-1790)

"It has long since come to my attention that people of accomplishment rarely sat back and let things happen to them. They went out and happened to things." -- Leonardo da Vinci (1452 – 1519)

"The function of muscle is to pull and not to push, except in the case of the genitals and the tongue." -- Leonardo da Vinci (1452 – 1519)

 



   

SQL: Get a list of Blocking Users

Blocking and locking is part of the normal operation of a database. The sys.SysProcesses System Compatibility View contains information about client and system processes that are running on an instance of SQL Server. The sys.SysProcesses System View can be used to retrieve a list of blocked and blocking processes. The following query can be used to see a list of blocked and blocking users. The query also displays the SQL command being executed which may assist in optimization resulting is less blocking. It is important to remember that blocking is normal and focus should be focused on long blocks/locks.

-- ##############################
-- Get a list of blocking users
-- ##############################
 
SELECT 
	spid
	,nt_username
	,hostname
	,program_name
	,blocked
	,waitresource
	,db_name(dbid) as Db
	,status
	,cmd
	,login_time 
	,datediff(ss, last_batch, getdate()) duration
	,(SELECT text FROM sys.dm_exec_sql_text(sql_handle)) AS sql_text
FROM 
	sys.sysprocesses
WHERE 
	(blocked > 0) 
	OR (waitresource != '')
UNION
SELECT 
	spid
	,nt_username
	,hostname
	,program_name
	,blocked
	,waitresource
	,db_name(dbid) as Db
	,status
	,cmd
	,login_time 
	,datediff(ss, last_batch, getdate()) duration
	,(SELECT text FROM sys.dm_exec_sql_text(sql_handle)) AS sql_text
FROM 
	sys.sysprocesses
WHERE 
	spid in (SELECT blocked FROM sys.sysprocesses WHERE blocked > 0) 
 
 -- #############################