/// /// Copyright © 2003-2008 JetBrains s.r.o. /// You may distribute under the terms of the GNU General Public License, as published by the Free Software Foundation, version 2 (see License.txt in the repository root folder). /// using System; using System.Threading; using System.Windows.Forms; using System35; using JetBrains.Annotations; namespace JetBrains.Omea.OpenAPI { // -- Interfaces for Omnia Mea async processing ------------------------------------ /// /// Specifies the priority of executing a job. /// public enum JobPriority { Lowest, BelowNormal, Normal, AboveNormal, Immediate } /// /// Represents a method which determines if the specified job should be cancelled. /// public delegate bool JobFilter( AbstractJob job ); // returns true - cancel, returns false - do not cancel /// /// Defines a base class for all asynchronous jobs. /// public abstract class AbstractJob { /// /// Override this method in order to perform an one-step job or to do /// initialization work for a many-steps job. /// protected abstract void Execute(); /// /// Sets the next portion of work to be executed. /// /// The delegate to be executed. /// The waitable handle which is used to signal that an /// AsyncProcesor should start execution of the next method. /// By default, the overriden Execute method is called by AsyncProcessor /// unconditionally, and only it. It is possible to continue job with execution of /// the method, which is invoked when the handle is signaled. Setting handle to null /// (this is not necessary) means that the job should not be continued. public void InvokeAfterWait([NotNull] MethodInvoker method, [NotNull] WaitHandle handle ) { _method = method; _handle = handle; } /// /// Gets next method to be executed. /// [NotNull] public MethodInvoker NextMethod { get { return _method ?? ( _method = Execute ); } } /// /// Gets next handle which should be waited to continue job. /// [CanBeNull] public WaitHandle NextWaitHandle { get { return _handle; } } /// /// Gets or sets timeout in milliseconds during which job is waited to continue. /// public int Timeout { get { return _timeout; } set { _timeout = value; } } /// /// Timeout handler. /// public event MethodInvoker OnTimeout; public void FireTimeout() { _handle = null; if( OnTimeout != null ) { OnTimeout(); } } private static readonly WaitHandle _nullHandle = new Mutex(); private MethodInvoker _method; private WaitHandle _handle = _nullHandle; private int _timeout = System.Threading.Timeout.Infinite; } /// /// Defines a base class for asynchronous jobs which have a name. /// public abstract class AbstractNamedJob : AbstractJob { /// /// Gets the name of the job. /// /// The name of the last executing job is displayed in the tooltip for /// the async processor status indicator in the status bar. [NotNull] abstract public string Name { get; } } /// /// Manages asynchronous execution of jobs in a thread. /// public interface IAsyncProcessor : IDisposable { /// /// Queues a job for asynchronous execution with normal priority. /// /// The job to be executed. /// True if the job was really queued, false if it was merged with an equal one. bool QueueJob([NotNull] AbstractJob job ); /// /// Queues a delegate for asynchronous execution with normal priority. /// /// The delegate to be executed. /// Actual parameters of method. /// True if the delegate was really queued, false if it was merged with an equal one. [Obsolete("An overload that takes the job name should be used.")] bool QueueJob([NotNull] Delegate method, params object[] args ); /// /// Queues a named delegate for asynchronous execution with normal priority. /// /// Name of operation. /// The delegate to be executed. /// Actual parameters of method. /// Name of operation is reflected by corresponding indicator light. /// True if the delegate was really queued, false if it was merged with an equal one. bool QueueJob([NotNull] string name, [NotNull] Delegate method, params object[] args ); /// /// Queues a named delegate for asynchronous execution with normal priority. /// These jobs are never merged. /// /// Name of operation. /// The delegate to be executed. Arguments should be passed via a closure. /// Name of operation is reflected by corresponding indicator light. void QueueJob( [NotNull] string name, [NotNull] Action action ); /// /// Queues a named delegate for asynchronous execution with normal priority. /// /// Name of operation. /// An optional identity. Jobs with equal non-Null identity will be merged together. /// The delegate to be executed. Arguments should be passed via a closure. /// Name of operation is reflected by corresponding indicator light. /// True if the delegate was really queued, False if it was merged with an equal one. bool QueueJob([NotNull] string name, [NotNull] object identity, [NotNull] Action action); /// /// Queues a job for asynchronous execution with specified priority. /// /// The priority of job. /// The job to be executed. /// True if the job was really queued, false if it was merged with an equal one. bool QueueJob( JobPriority priority, [NotNull] AbstractJob job ); /// /// Queues a delegate for asynchronous execution with specified priority. /// /// The priority of this job. /// The delegate to be executed. /// Actual parameters of method. /// True if the delegate was really queued, false if it was merged with an equal one. [Obsolete("An overload that takes the job name should be used.")] bool QueueJob( JobPriority priority, [NotNull] Delegate method, params object[] args ); /// /// Queues a named delegate for asynchronous execution with specified priority. /// /// The priority of this job. /// Name of operation. /// The delegate to be executed. /// Actual parameters of method. /// Name of operation is reflected by corresponding indicator light. /// True if the delegate was really queued, false if it was merged with an equal one. bool QueueJob( JobPriority priority, [NotNull] string name, [NotNull] Delegate method, params object[] args ); /// /// Queues a named delegate for asynchronous execution with specified priority. /// These jobs are never merged. /// /// The priority of this job. /// Name of operation. /// The delegate to be executed. Arguments should be passed via a closure. /// Name of operation is reflected by corresponding indicator light. void QueueJob( JobPriority priority, [NotNull] string name, [NotNull] Action action ); /// /// Queues a named delegate for asynchronous execution with specified priority. /// /// The priority of this job. /// Name of operation. /// An optional identity. Jobs with equal non-Null identity will be merged together. /// The delegate to be executed. Arguments should be passed via a closure. /// Name of operation is reflected by corresponding indicator light. /// True if the delegate was really queued, False if it was merged with an equal one. bool QueueJob( JobPriority priority, [NotNull] string name, [NotNull] object identity, [NotNull] Action action); /// /// Queues a job for execution at specified time. /// /// The time when job should be executed. /// The job to be executed. /// If time has passed, job is executed immediately. void QueueJobAt( DateTime dateTime, [NotNull] AbstractJob job ); /// /// Queues a delegate for execution at specified time. /// /// The time when delegate should be executed. /// The delegate to be executed. /// Actual parameters of method. /// If time has passed, job is executed immediately. [Obsolete("An overload that takes the job name should be used.")] void QueueJobAt( DateTime dateTime, [NotNull] Delegate method, params object[] args ); /// /// Queues a named delegate for execution at specified time. /// /// The time when delegate should be executed. /// Name of operation. /// The delegate to be executed. /// Actual parameters of method. /// If time has passed, job is executed immediately. Name of operation is reflected by corresponding indicator light. void QueueJobAt( DateTime dateTime, [NotNull] string name, [NotNull] Delegate method, params object[] args ); /// /// Queues a named delegate for execution at specified time. /// /// The time when delegate should be executed. /// Name of operation. /// The delegate to be executed. Arguments should be passed via a closure. /// If time has passed, job is executed immediately. Name of operation is reflected by corresponding indicator light. void QueueJobAt( DateTime dateTime, [NotNull] string name, [NotNull] Action action ); /// /// Queues a job for execution with normal priority in idle mode. /// /// The job to be executed in idle mode. /// void QueueIdleJob([NotNull] AbstractJob job ); /// /// Queues a job for execution with specified priority in idle mode. /// /// The priority of idle job. /// The job to be executed in idle mode. /// void QueueIdleJob( JobPriority priority, [NotNull] AbstractJob job ); /// /// Queues a job for synchronous execution and waits until it is finished. /// /// The job to be executed. /// Jobs to be run are queued with the immediate priority. /// On attempt to run two or more equal jobs simultaneously the AsyncProcessorException is thrown. void RunJob([NotNull] AbstractJob job ); /// /// Queues a delegate for synchronous execution and waits until it is finished. /// /// The delegate to be executed. /// Actual parameters of method. /// Jobs to be run are queued with the immediate priority. /// On attempt to run two or more equal jobs simultaneously the AsyncProcessorException is thrown. /// Actual value returned by the method. [Obsolete("An overload that takes the job name should be used.")] object RunJob([NotNull] Delegate method, params object[] args ); /// /// Queues a named delegate for synchronous execution and waits until it is finished. /// /// Name of operation. /// The delegate to be executed. /// Actual parameters of method. /// Jobs to be run are queued with the immediate priority. /// On attempt to run two or more equal jobs simultaneously the AsyncProcessorException is thrown. /// Name of operation is reflected by corresponding indicator light. /// Actual value returned by the method. object RunJob([NotNull] string name, [NotNull] Delegate method, params object[] args ); /// /// Queues a named delegate for synchronous execution and waits until it is finished. /// /// Name of operation. /// The delegate to be executed. Arguments and a return value should be passed via a closure. /// Jobs to be run are queued with the immediate priority. /// On attempt to run two or more equal jobs simultaneously the AsyncProcessorException is thrown. /// Name of operation is reflected by corresponding indicator light. /// Whether the execution succeeded. bool RunJob( [NotNull] string name, [NotNull] Action action ); /// /// Queues a job for synchronous execution and waits until it is finished. /// /// The job to be executed. /// Jobs to be run are queued with the immediate priority. /// Unlike IAsyncProcessor.RunJob, attempt to run a job equal to another one already queued /// is silently skipped. void RunUniqueJob([NotNull] AbstractJob job ); /// /// Queues a delegate for synchronous execution and waits until it is finished. /// /// The delegate to be executed. /// Actual parameters of method. /// Jobs to be run are queued with the immediate priority. /// Unlike IAsyncProcessor.RunJob, attempt to run a delegate equal to another one already queued /// is silently skipped. /// Actual value returned by the method or null, if the delegate was skipped. [Obsolete("An overload that takes the job name should be used.")] object RunUniqueJob([NotNull] Delegate method, params object[] args ); /// /// Queues a named delegate for synchronous execution and waits until it is finished. /// /// Name of operation. /// The delegate to be executed. /// Actual parameters of method. /// Jobs to be run are queued with the immediate priority. /// Unlike IAsyncProcessor.RunJob, attempt to run a delegate equal to another one already queued /// is silently skipped. Name of operation is reflected by corresponding indicator light. /// Actual value returned by the method or null, if the delegate was skipped. object RunUniqueJob([NotNull] string name, [NotNull] Delegate method, params object[] args ); /// /// Cancels earlier queued jobs that haven't started and match the filter. /// /// Filter for cancellation. void CancelJobs([NotNull] JobFilter filter ); /// /// Cancels earlier queued delegates that haven't started and equal to specified method. /// /// Method to be cancelled. void CancelJobs([NotNull] Delegate method ); /// /// Cancels earlier queued jobs that haven't started and equal to specified job. /// /// Job to be cancelled. void CancelJobs([NotNull] AbstractJob job ); /// /// Cancels all queued jobs that haven't started. /// void CancelJobs(); /// /// Cancels timed jobs that haven't started and match the filter. /// /// Filter for cancellation. void CancelTimedJobs([NotNull] JobFilter filter ); /// /// Cancels timed delegates that haven't started and equal to specified method. /// /// Method to be cancelled. void CancelTimedJobs([NotNull] Delegate method ); /// /// Cancels timed jobs that haven't started and equal to specified job. /// /// Job to be cancelled. void CancelTimedJobs([NotNull] AbstractJob job ); /// /// Returns true if current thread is owned by the AsyncProcessor. /// /// 2.0 bool IsOwnerThread { get; } /// /// Returns the name of currently executed job. Empty name means that no named job is executed. /// [NotNull] string CurrentJobName { get; } /// /// Event handler invoked before starting a job. /// event EventHandler JobStarting; /// /// Event handler invoked after a job finished. /// event EventHandler JobFinished; /// /// Event handler invoked when AsyncProcessor's main queue of jobs becomes empty. /// /// Main queue of jobs doesn't contain timed or idle jobs. event EventHandler QueueGotEmpty; } }