///
/// 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;
}
}