/* * Process Hacker * * Copyright (C) 2008 wj32 * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ using System; using System.Collections.Generic; using System.Text; using System.Threading; namespace ProcessHacker { /// /// A generic delegate which is used when updating the dictionary. /// public delegate void ProviderUpdateOnce(); /// /// Represents an invoke method (either Invoke() or BeginInvoke() on a form). /// /// The method to invoke. /// The arguments to pass to the method. /// public delegate object ProviderInvokeMethod(Delegate method, params object[] args); /// /// Represents a handler called when a dictionary item is added. /// /// The added item. public delegate void ProviderDictionaryAdded(object item); /// /// Represents a handler called when a dictionary item is modified. /// /// The modified item. public delegate void ProviderDictionaryModified(object item); /// /// Represents a handler called when a dictionary item is removed. /// /// The removed item. public delegate void ProviderDictionaryRemoved(object item); /// /// Represents a handler called when an error occurs while updating. /// /// The raised exception. public delegate void ProviderError(Exception ex); /// /// Provides services for continuously updating a dictionary. /// public class Provider { private delegate void InvokeDelegate(object item); /// /// Occurs when the provider needs to update the dictionary (after waiting the duration of the interval). /// protected event ProviderUpdateOnce ProviderUpdate; /// /// Occurs when the provider needs to invoke a method on another thread. /// public ProviderInvokeMethod Invoke; /// /// Occurs when the provider adds an item to the dictionary. /// public event ProviderDictionaryAdded DictionaryAdded; /// /// Occurs when the provider modifies an item in the dictionary. /// public event ProviderDictionaryModified DictionaryModified; /// /// Occurs when the provider removes an item from the dictionary. /// public event ProviderDictionaryRemoved DictionaryRemoved; /// /// Occurs when an exception is raised while updating. /// public event ProviderError Error; Thread _thread; Dictionary _dictionary; bool _busy = false; bool _enabled = false; bool _useInvoke = false; int _interval; /// /// Creates a new instance of the Provider class. /// public Provider() { _dictionary = new Dictionary(); _thread = new Thread(new ThreadStart(Update)); _thread.Priority = ThreadPriority.Lowest; _thread.Start(); } /// /// Determines whether the provider is currently updating. /// public bool Busy { get { return _busy; } } /// /// Determines whether the provider should update. /// public bool Enabled { get { return _enabled; } set { _enabled = value; } } /// /// Determines whether the provider should invoke the DictionaryAdded, Modified and Removed events. /// public bool UseInvoke { get { return _useInvoke; } set { _useInvoke = value; } } /// /// Gets or sets the interval to wait between each update. /// public int Interval { get { return _interval; } set { _interval = value; } } /// /// Gets the dictionary. /// public Dictionary Dictionary { get { return _dictionary; } protected set { _dictionary = value; } } private void Update() { while (true) { if (_enabled) { _busy = true; if (ProviderUpdate != null) { try { ProviderUpdate(); } catch (Exception ex) { if (Error != null) Error(ex); } } _busy = false; } Thread.Sleep(_interval); } } /// /// Removes all handlers from the DictionaryAdded, Modified and Removed events. /// public void ClearEvents() { DictionaryAdded = null; DictionaryModified = null; DictionaryRemoved = null; } public void Kill() { _thread.Abort(); } private void CallEvent(Delegate e, object item, bool useInvoke) { if (useInvoke) { this.Invoke(new InvokeDelegate(delegate(object item_) { CallEvent(e, item_, false); }), item); } else { if (e != null) e.DynamicInvoke(item); } } protected void CallDictionaryAdded(object item) { CallDictionaryAdded(item, _useInvoke); } protected void CallDictionaryAdded(object item, bool useInvoke) { CallEvent(this.DictionaryAdded, item, useInvoke); } protected void CallDictionaryModified(object item) { CallDictionaryModified(item, _useInvoke); } protected void CallDictionaryModified(object item, bool useInvoke) { CallEvent(this.DictionaryModified, item, useInvoke); } protected void CallDictionaryRemoved(object item) { CallDictionaryRemoved(item, _useInvoke); } protected void CallDictionaryRemoved(object item, bool useInvoke) { CallEvent(this.DictionaryRemoved, item, useInvoke); } } }