From 1a47ff8094ee414a47aebd310826906d89428a09 Mon Sep 17 00:00:00 2001
From: Teravus Ovares
Date: Fri, 30 May 2008 12:27:06 +0000
Subject: * This is Melanie's XEngine script engine. I've not tested this real
well, however, it's confirmed to compile and OpenSimulator to run
successfully without this script engine active.
---
ThirdParty/SmartThreadPool/WorkItem.cs | 1035 ++++++++++++++++++++++++++++++++
1 file changed, 1035 insertions(+)
create mode 100644 ThirdParty/SmartThreadPool/WorkItem.cs
(limited to 'ThirdParty/SmartThreadPool/WorkItem.cs')
diff --git a/ThirdParty/SmartThreadPool/WorkItem.cs b/ThirdParty/SmartThreadPool/WorkItem.cs
new file mode 100644
index 0000000..d0c0524
--- /dev/null
+++ b/ThirdParty/SmartThreadPool/WorkItem.cs
@@ -0,0 +1,1035 @@
+// Ami Bar
+// amibar@gmail.com
+
+using System;
+using System.Threading;
+using System.Diagnostics;
+
+namespace Amib.Threading.Internal
+{
+ #region WorkItem Delegate
+
+ ///
+ /// An internal delegate to call when the WorkItem starts or completes
+ ///
+ internal delegate void WorkItemStateCallback(WorkItem workItem);
+
+ #endregion
+
+ #region IInternalWorkItemResult interface
+
+ public class CanceledWorkItemsGroup
+ {
+ public readonly static CanceledWorkItemsGroup NotCanceledWorkItemsGroup = new CanceledWorkItemsGroup();
+
+ private bool _isCanceled = false;
+ public bool IsCanceled
+ {
+ get { return _isCanceled; }
+ set { _isCanceled = value; }
+ }
+ }
+
+ internal interface IInternalWorkItemResult
+ {
+ event WorkItemStateCallback OnWorkItemStarted;
+ event WorkItemStateCallback OnWorkItemCompleted;
+ }
+
+ #endregion
+
+ #region IWorkItem interface
+
+ public interface IWorkItem
+ {
+
+ }
+
+ #endregion
+
+ #region WorkItem class
+
+ ///
+ /// Holds a callback delegate and the state for that delegate.
+ ///
+ public class WorkItem : IHasWorkItemPriority, IWorkItem
+ {
+ #region WorkItemState enum
+
+ ///
+ /// Indicates the state of the work item in the thread pool
+ ///
+ private enum WorkItemState
+ {
+ InQueue,
+ InProgress,
+ Completed,
+ Canceled,
+ }
+
+ #endregion
+
+ #region Member Variables
+
+ public Thread currentThread;
+
+ ///
+ /// Callback delegate for the callback.
+ ///
+ private WorkItemCallback _callback;
+
+ ///
+ /// State with which to call the callback delegate.
+ ///
+ private object _state;
+
+ ///
+ /// Stores the caller's context
+ ///
+ private CallerThreadContext _callerContext;
+
+ ///
+ /// Holds the result of the mehtod
+ ///
+ private object _result;
+
+ ///
+ /// Hold the exception if the method threw it
+ ///
+ private Exception _exception;
+
+ ///
+ /// Hold the state of the work item
+ ///
+ private WorkItemState _workItemState;
+
+ ///
+ /// A ManualResetEvent to indicate that the result is ready
+ ///
+ private ManualResetEvent _workItemCompleted;
+
+ ///
+ /// A reference count to the _workItemCompleted.
+ /// When it reaches to zero _workItemCompleted is Closed
+ ///
+ private int _workItemCompletedRefCount;
+
+ ///
+ /// Represents the result state of the work item
+ ///
+ private WorkItemResult _workItemResult;
+
+ ///
+ /// Work item info
+ ///
+ private WorkItemInfo _workItemInfo;
+
+ ///
+ /// Called when the WorkItem starts
+ ///
+ private event WorkItemStateCallback _workItemStartedEvent;
+
+ ///
+ /// Called when the WorkItem completes
+ ///
+ private event WorkItemStateCallback _workItemCompletedEvent;
+
+ ///
+ /// A reference to an object that indicates whatever the
+ /// WorkItemsGroup has been canceled
+ ///
+ private CanceledWorkItemsGroup _canceledWorkItemsGroup = CanceledWorkItemsGroup.NotCanceledWorkItemsGroup;
+
+ ///
+ /// The work item group this work item belong to.
+ ///
+ ///
+ private IWorkItemsGroup _workItemsGroup;
+
+ #region Performance Counter fields
+
+ ///
+ /// The time when the work items is queued.
+ /// Used with the performance counter.
+ ///
+ private DateTime _queuedTime;
+
+ ///
+ /// The time when the work items starts its execution.
+ /// Used with the performance counter.
+ ///
+ private DateTime _beginProcessTime;
+
+ ///
+ /// The time when the work items ends its execution.
+ /// Used with the performance counter.
+ ///
+ private DateTime _endProcessTime;
+
+ #endregion
+
+ #endregion
+
+ #region Properties
+
+ public TimeSpan WaitingTime
+ {
+ get
+ {
+ return (_beginProcessTime - _queuedTime);
+ }
+ }
+
+ public TimeSpan ProcessTime
+ {
+ get
+ {
+ return (_endProcessTime - _beginProcessTime);
+ }
+ }
+
+ #endregion
+
+ #region Construction
+
+ ///
+ /// Initialize the callback holding object.
+ ///
+ /// Callback delegate for the callback.
+ /// State with which to call the callback delegate.
+ ///
+ /// We assume that the WorkItem object is created within the thread
+ /// that meant to run the callback
+ public WorkItem(
+ IWorkItemsGroup workItemsGroup,
+ WorkItemInfo workItemInfo,
+ WorkItemCallback callback,
+ object state)
+ {
+ _workItemsGroup = workItemsGroup;
+ _workItemInfo = workItemInfo;
+
+ if (_workItemInfo.UseCallerCallContext || _workItemInfo.UseCallerHttpContext)
+ {
+ _callerContext = CallerThreadContext.Capture(_workItemInfo.UseCallerCallContext, _workItemInfo.UseCallerHttpContext);
+ }
+
+ _callback = callback;
+ _state = state;
+ _workItemResult = new WorkItemResult(this);
+ Initialize();
+ }
+
+ internal void Initialize()
+ {
+ _workItemState = WorkItemState.InQueue;
+ _workItemCompleted = null;
+ _workItemCompletedRefCount = 0;
+ }
+
+ internal bool WasQueuedBy(IWorkItemsGroup workItemsGroup)
+ {
+ return (workItemsGroup == _workItemsGroup);
+ }
+
+
+ #endregion
+
+ #region Methods
+
+ public CanceledWorkItemsGroup CanceledWorkItemsGroup
+ {
+ get
+ {
+ return _canceledWorkItemsGroup;
+ }
+
+ set
+ {
+ _canceledWorkItemsGroup = value;
+ }
+ }
+
+ ///
+ /// Change the state of the work item to in progress if it wasn't canceled.
+ ///
+ ///
+ /// Return true on success or false in case the work item was canceled.
+ /// If the work item needs to run a post execute then the method will return true.
+ ///
+ public bool StartingWorkItem()
+ {
+ _beginProcessTime = DateTime.Now;
+
+ lock(this)
+ {
+ if (IsCanceled)
+ {
+ bool result = false;
+ if ((_workItemInfo.PostExecuteWorkItemCallback != null) &&
+ ((_workItemInfo.CallToPostExecute & CallToPostExecute.WhenWorkItemCanceled) == CallToPostExecute.WhenWorkItemCanceled))
+ {
+ result = true;
+ }
+
+ return result;
+ }
+
+ Debug.Assert(WorkItemState.InQueue == GetWorkItemState());
+
+ SetWorkItemState(WorkItemState.InProgress);
+ }
+
+ return true;
+ }
+
+ ///
+ /// Execute the work item and the post execute
+ ///
+ public void Execute()
+ {
+ CallToPostExecute currentCallToPostExecute = 0;
+
+ // Execute the work item if we are in the correct state
+ switch(GetWorkItemState())
+ {
+ case WorkItemState.InProgress:
+ currentCallToPostExecute |= CallToPostExecute.WhenWorkItemNotCanceled;
+ ExecuteWorkItem();
+ break;
+ case WorkItemState.Canceled:
+ currentCallToPostExecute |= CallToPostExecute.WhenWorkItemCanceled;
+ break;
+ default:
+ Debug.Assert(false);
+ throw new NotSupportedException();
+ }
+
+ // Run the post execute as needed
+ if ((currentCallToPostExecute & _workItemInfo.CallToPostExecute) != 0)
+ {
+ PostExecute();
+ }
+
+ _endProcessTime = DateTime.Now;
+ }
+
+ internal void FireWorkItemCompleted()
+ {
+ try
+ {
+ if (null != _workItemCompletedEvent)
+ {
+ _workItemCompletedEvent(this);
+ }
+ }
+ catch // Ignore exceptions
+ {}
+ }
+
+ ///
+ /// Execute the work item
+ ///
+ private void ExecuteWorkItem()
+ {
+ CallerThreadContext ctc = null;
+ if (null != _callerContext)
+ {
+ ctc = CallerThreadContext.Capture(_callerContext.CapturedCallContext, _callerContext.CapturedHttpContext);
+ CallerThreadContext.Apply(_callerContext);
+ }
+
+ Exception exception = null;
+ object result = null;
+
+ try
+ {
+ result = _callback(_state);
+ }
+ catch (Exception e)
+ {
+ // Save the exception so we can rethrow it later
+ exception = e;
+ }
+
+ if (null != _callerContext)
+ {
+ CallerThreadContext.Apply(ctc);
+ }
+
+ SetResult(result, exception);
+ }
+
+ ///
+ /// Runs the post execute callback
+ ///
+ private void PostExecute()
+ {
+ if (null != _workItemInfo.PostExecuteWorkItemCallback)
+ {
+ try
+ {
+ _workItemInfo.PostExecuteWorkItemCallback(this._workItemResult);
+ }
+ catch (Exception e)
+ {
+ Debug.Assert(null != e);
+ }
+ }
+ }
+
+ ///
+ /// Set the result of the work item to return
+ ///
+ /// The result of the work item
+ internal void SetResult(object result, Exception exception)
+ {
+ _result = result;
+ _exception = exception;
+ SignalComplete(false);
+ }
+
+ ///
+ /// Returns the work item result
+ ///
+ /// The work item result
+ internal IWorkItemResult GetWorkItemResult()
+ {
+ return _workItemResult;
+ }
+
+ ///
+ /// Wait for all work items to complete
+ ///
+ /// Array of work item result objects
+ /// The number of milliseconds to wait, or Timeout.Infinite (-1) to wait indefinitely.
+ ///
+ /// true to exit the synchronization domain for the context before the wait (if in a synchronized context), and reacquire it; otherwise, false.
+ ///
+ /// A cancel wait handle to interrupt the wait if needed
+ ///
+ /// true when every work item in workItemResults has completed; otherwise false.
+ ///
+ internal static bool WaitAll(
+ IWorkItemResult [] workItemResults,
+ int millisecondsTimeout,
+ bool exitContext,
+ WaitHandle cancelWaitHandle)
+ {
+ if (0 == workItemResults.Length)
+ {
+ return true;
+ }
+
+ bool success;
+ WaitHandle [] waitHandles = new WaitHandle[workItemResults.Length];;
+ GetWaitHandles(workItemResults, waitHandles);
+
+ if ((null == cancelWaitHandle) && (waitHandles.Length <= 64))
+ {
+ success = WaitHandle.WaitAll(waitHandles, millisecondsTimeout, exitContext);
+ }
+ else
+ {
+ success = true;
+ int millisecondsLeft = millisecondsTimeout;
+ DateTime start = DateTime.Now;
+
+ WaitHandle [] whs;
+ if (null != cancelWaitHandle)
+ {
+ whs = new WaitHandle [] { null, cancelWaitHandle };
+ }
+ else
+ {
+ whs = new WaitHandle [] { null };
+ }
+
+ bool waitInfinitely = (Timeout.Infinite == millisecondsTimeout);
+ // Iterate over the wait handles and wait for each one to complete.
+ // We cannot use WaitHandle.WaitAll directly, because the cancelWaitHandle
+ // won't affect it.
+ // Each iteration we update the time left for the timeout.
+ for(int i = 0; i < workItemResults.Length; ++i)
+ {
+ // WaitAny don't work with negative numbers
+ if (!waitInfinitely && (millisecondsLeft < 0))
+ {
+ success = false;
+ break;
+ }
+
+ whs[0] = waitHandles[i];
+ int result = WaitHandle.WaitAny(whs, millisecondsLeft, exitContext);
+ if((result > 0) || (WaitHandle.WaitTimeout == result))
+ {
+ success = false;
+ break;
+ }
+
+ if(!waitInfinitely)
+ {
+ // Update the time left to wait
+ TimeSpan ts = DateTime.Now - start;
+ millisecondsLeft = millisecondsTimeout - (int)ts.TotalMilliseconds;
+ }
+ }
+ }
+ // Release the wait handles
+ ReleaseWaitHandles(workItemResults);
+
+ return success;
+ }
+
+ ///
+ /// Waits for any of the work items in the specified array to complete, cancel, or timeout
+ ///
+ /// Array of work item result objects
+ /// The number of milliseconds to wait, or Timeout.Infinite (-1) to wait indefinitely.
+ ///
+ /// true to exit the synchronization domain for the context before the wait (if in a synchronized context), and reacquire it; otherwise, false.
+ ///
+ /// A cancel wait handle to interrupt the wait if needed
+ ///
+ /// The array index of the work item result that satisfied the wait, or WaitTimeout if no work item result satisfied the wait and a time interval equivalent to millisecondsTimeout has passed or the work item has been canceled.
+ ///
+ internal static int WaitAny(
+ IWorkItemResult [] workItemResults,
+ int millisecondsTimeout,
+ bool exitContext,
+ WaitHandle cancelWaitHandle)
+ {
+ WaitHandle [] waitHandles = null;
+
+ if (null != cancelWaitHandle)
+ {
+ waitHandles = new WaitHandle[workItemResults.Length+1];
+ GetWaitHandles(workItemResults, waitHandles);
+ waitHandles[workItemResults.Length] = cancelWaitHandle;
+ }
+ else
+ {
+ waitHandles = new WaitHandle[workItemResults.Length];
+ GetWaitHandles(workItemResults, waitHandles);
+ }
+
+ int result = WaitHandle.WaitAny(waitHandles, millisecondsTimeout, exitContext);
+
+ // Treat cancel as timeout
+ if (null != cancelWaitHandle)
+ {
+ if (result == workItemResults.Length)
+ {
+ result = WaitHandle.WaitTimeout;
+ }
+ }
+
+ ReleaseWaitHandles(workItemResults);
+
+ return result;
+ }
+
+ ///
+ /// Fill an array of wait handles with the work items wait handles.
+ ///
+ /// An array of work item results
+ /// An array of wait handles to fill
+ private static void GetWaitHandles(
+ IWorkItemResult [] workItemResults,
+ WaitHandle [] waitHandles)
+ {
+ for(int i = 0; i < workItemResults.Length; ++i)
+ {
+ WorkItemResult wir = workItemResults[i] as WorkItemResult;
+ Debug.Assert(null != wir, "All workItemResults must be WorkItemResult objects");
+
+ waitHandles[i] = wir.GetWorkItem().GetWaitHandle();
+ }
+ }
+
+ ///
+ /// Release the work items' wait handles
+ ///
+ /// An array of work item results
+ private static void ReleaseWaitHandles(IWorkItemResult [] workItemResults)
+ {
+ for(int i = 0; i < workItemResults.Length; ++i)
+ {
+ WorkItemResult wir = workItemResults[i] as WorkItemResult;
+
+ wir.GetWorkItem().ReleaseWaitHandle();
+ }
+ }
+
+
+ #endregion
+
+ #region Private Members
+
+ private WorkItemState GetWorkItemState()
+ {
+ if (_canceledWorkItemsGroup.IsCanceled)
+ {
+ return WorkItemState.Canceled;
+ }
+ return _workItemState;
+
+ }
+ ///
+ /// Sets the work item's state
+ ///
+ /// The state to set the work item to
+ private void SetWorkItemState(WorkItemState workItemState)
+ {
+ lock(this)
+ {
+ _workItemState = workItemState;
+ }
+ }
+
+ ///
+ /// Signals that work item has been completed or canceled
+ ///
+ /// Indicates that the work item has been canceled
+ private void SignalComplete(bool canceled)
+ {
+ SetWorkItemState(canceled ? WorkItemState.Canceled : WorkItemState.Completed);
+ lock(this)
+ {
+ // If someone is waiting then signal.
+ if (null != _workItemCompleted)
+ {
+ _workItemCompleted.Set();
+ }
+ }
+ }
+
+ internal void WorkItemIsQueued()
+ {
+ _queuedTime = DateTime.Now;
+ }
+
+ #endregion
+
+ #region Members exposed by WorkItemResult
+
+ ///
+ /// Cancel the work item if it didn't start running yet.
+ ///
+ /// Returns true on success or false if the work item is in progress or already completed
+ private bool Cancel()
+ {
+ lock(this)
+ {
+ switch(GetWorkItemState())
+ {
+ case WorkItemState.Canceled:
+ //Debug.WriteLine("Work item already canceled");
+ return true;
+ case WorkItemState.Completed:
+ case WorkItemState.InProgress:
+ //Debug.WriteLine("Work item cannot be canceled");
+ return false;
+ case WorkItemState.InQueue:
+ // Signal to the wait for completion that the work
+ // item has been completed (canceled). There is no
+ // reason to wait for it to get out of the queue
+ SignalComplete(true);
+ //Debug.WriteLine("Work item canceled");
+ return true;
+ }
+ }
+ return false;
+ }
+
+ ///
+ /// Get the result of the work item.
+ /// If the work item didn't run yet then the caller waits for the result, timeout, or cancel.
+ /// In case of error the method throws and exception
+ ///
+ /// The result of the work item
+ private object GetResult(
+ int millisecondsTimeout,
+ bool exitContext,
+ WaitHandle cancelWaitHandle)
+ {
+ Exception e = null;
+ object result = GetResult(millisecondsTimeout, exitContext, cancelWaitHandle, out e);
+ if (null != e)
+ {
+ throw new WorkItemResultException("The work item caused an excpetion, see the inner exception for details", e);
+ }
+ return result;
+ }
+
+ ///
+ /// Get the result of the work item.
+ /// If the work item didn't run yet then the caller waits for the result, timeout, or cancel.
+ /// In case of error the e argument is filled with the exception
+ ///
+ /// The result of the work item
+ private object GetResult(
+ int millisecondsTimeout,
+ bool exitContext,
+ WaitHandle cancelWaitHandle,
+ out Exception e)
+ {
+ e = null;
+
+ // Check for cancel
+ if (WorkItemState.Canceled == GetWorkItemState())
+ {
+ throw new WorkItemCancelException("Work item canceled");
+ }
+
+ // Check for completion
+ if (IsCompleted)
+ {
+ e = _exception;
+ return _result;
+ }
+
+ // If no cancelWaitHandle is provided
+ if (null == cancelWaitHandle)
+ {
+ WaitHandle wh = GetWaitHandle();
+
+ bool timeout = !wh.WaitOne(millisecondsTimeout, exitContext);
+
+ ReleaseWaitHandle();
+
+ if (timeout)
+ {
+ throw new WorkItemTimeoutException("Work item timeout");
+ }
+ }
+ else
+ {
+ WaitHandle wh = GetWaitHandle();
+ int result = WaitHandle.WaitAny(new WaitHandle[] { wh, cancelWaitHandle });
+ ReleaseWaitHandle();
+
+ switch(result)
+ {
+ case 0:
+ // The work item signaled
+ // Note that the signal could be also as a result of canceling the
+ // work item (not the get result)
+ break;
+ case 1:
+ case WaitHandle.WaitTimeout:
+ throw new WorkItemTimeoutException("Work item timeout");
+ default:
+ Debug.Assert(false);
+ break;
+
+ }
+ }
+
+ // Check for cancel
+ if (WorkItemState.Canceled == GetWorkItemState())
+ {
+ throw new WorkItemCancelException("Work item canceled");
+ }
+
+ Debug.Assert(IsCompleted);
+
+ e = _exception;
+
+ // Return the result
+ return _result;
+ }
+
+ ///
+ /// A wait handle to wait for completion, cancel, or timeout
+ ///
+ private WaitHandle GetWaitHandle()
+ {
+ lock(this)
+ {
+ if (null == _workItemCompleted)
+ {
+ _workItemCompleted = new ManualResetEvent(IsCompleted);
+ }
+ ++_workItemCompletedRefCount;
+ }
+ return _workItemCompleted;
+ }
+
+ private void ReleaseWaitHandle()
+ {
+ lock(this)
+ {
+ if (null != _workItemCompleted)
+ {
+ --_workItemCompletedRefCount;
+ if (0 == _workItemCompletedRefCount)
+ {
+ _workItemCompleted.Close();
+ _workItemCompleted = null;
+ }
+ }
+ }
+ }
+
+ ///
+ /// Returns true when the work item has completed or canceled
+ ///
+ private bool IsCompleted
+ {
+ get
+ {
+ lock(this)
+ {
+ WorkItemState workItemState = GetWorkItemState();
+ return ((workItemState == WorkItemState.Completed) ||
+ (workItemState == WorkItemState.Canceled));
+ }
+ }
+ }
+
+ ///
+ /// Returns true when the work item has canceled
+ ///
+ public bool IsCanceled
+ {
+ get
+ {
+ lock(this)
+ {
+ return (GetWorkItemState() == WorkItemState.Canceled);
+ }
+ }
+ }
+
+ #endregion
+
+ #region IHasWorkItemPriority Members
+
+ ///
+ /// Returns the priority of the work item
+ ///
+ public WorkItemPriority WorkItemPriority
+ {
+ get
+ {
+ return _workItemInfo.WorkItemPriority;
+ }
+ }
+
+ #endregion
+
+ internal event WorkItemStateCallback OnWorkItemStarted
+ {
+ add
+ {
+ _workItemStartedEvent += value;
+ }
+ remove
+ {
+ _workItemStartedEvent -= value;
+ }
+ }
+
+ internal event WorkItemStateCallback OnWorkItemCompleted
+ {
+ add
+ {
+ _workItemCompletedEvent += value;
+ }
+ remove
+ {
+ _workItemCompletedEvent -= value;
+ }
+ }
+
+
+ #region WorkItemResult class
+
+ private class WorkItemResult : IWorkItemResult, IInternalWorkItemResult
+ {
+ ///
+ /// A back reference to the work item
+ ///
+ private WorkItem _workItem;
+
+ public WorkItemResult(WorkItem workItem)
+ {
+ _workItem = workItem;
+ }
+
+ internal WorkItem GetWorkItem()
+ {
+ return _workItem;
+ }
+
+ #region IWorkItemResult Members
+
+ public bool IsCompleted
+ {
+ get
+ {
+ return _workItem.IsCompleted;
+ }
+ }
+
+ public void Abort()
+ {
+ _workItem.Abort();
+ }
+
+ public bool IsCanceled
+ {
+ get
+ {
+ return _workItem.IsCanceled;
+ }
+ }
+
+ public object GetResult()
+ {
+ return _workItem.GetResult(Timeout.Infinite, true, null);
+ }
+
+ public object GetResult(int millisecondsTimeout, bool exitContext)
+ {
+ return _workItem.GetResult(millisecondsTimeout, exitContext, null);
+ }
+
+ public object GetResult(TimeSpan timeout, bool exitContext)
+ {
+ return _workItem.GetResult((int)timeout.TotalMilliseconds, exitContext, null);
+ }
+
+ public object GetResult(int millisecondsTimeout, bool exitContext, WaitHandle cancelWaitHandle)
+ {
+ return _workItem.GetResult(millisecondsTimeout, exitContext, cancelWaitHandle);
+ }
+
+ public object GetResult(TimeSpan timeout, bool exitContext, WaitHandle cancelWaitHandle)
+ {
+ return _workItem.GetResult((int)timeout.TotalMilliseconds, exitContext, cancelWaitHandle);
+ }
+
+ public object GetResult(out Exception e)
+ {
+ return _workItem.GetResult(Timeout.Infinite, true, null, out e);
+ }
+
+ public object GetResult(int millisecondsTimeout, bool exitContext, out Exception e)
+ {
+ return _workItem.GetResult(millisecondsTimeout, exitContext, null, out e);
+ }
+
+ public object GetResult(TimeSpan timeout, bool exitContext, out Exception e)
+ {
+ return _workItem.GetResult((int)timeout.TotalMilliseconds, exitContext, null, out e);
+ }
+
+ public object GetResult(int millisecondsTimeout, bool exitContext, WaitHandle cancelWaitHandle, out Exception e)
+ {
+ return _workItem.GetResult(millisecondsTimeout, exitContext, cancelWaitHandle, out e);
+ }
+
+ public object GetResult(TimeSpan timeout, bool exitContext, WaitHandle cancelWaitHandle, out Exception e)
+ {
+ return _workItem.GetResult((int)timeout.TotalMilliseconds, exitContext, cancelWaitHandle, out e);
+ }
+
+ public bool Cancel()
+ {
+ return _workItem.Cancel();
+ }
+
+ public object State
+ {
+ get
+ {
+ return _workItem._state;
+ }
+ }
+
+ public WorkItemPriority WorkItemPriority
+ {
+ get
+ {
+ return _workItem._workItemInfo.WorkItemPriority;
+ }
+ }
+
+ ///
+ /// Return the result, same as GetResult()
+ ///
+ public object Result
+ {
+ get { return GetResult(); }
+ }
+
+ ///
+ /// Returns the exception if occured otherwise returns null.
+ /// This value is valid only after the work item completed,
+ /// before that it is always null.
+ ///
+ public object Exception
+ {
+ get { return _workItem._exception; }
+ }
+
+ #endregion
+
+ #region IInternalWorkItemResult Members
+
+ public event WorkItemStateCallback OnWorkItemStarted
+ {
+ add
+ {
+ _workItem.OnWorkItemStarted += value;
+ }
+ remove
+ {
+ _workItem.OnWorkItemStarted -= value;
+ }
+ }
+
+
+ public event WorkItemStateCallback OnWorkItemCompleted
+ {
+ add
+ {
+ _workItem.OnWorkItemCompleted += value;
+ }
+ remove
+ {
+ _workItem.OnWorkItemCompleted -= value;
+ }
+ }
+
+ #endregion
+ }
+
+ #endregion
+
+ public void DisposeOfState()
+ {
+ if (_workItemInfo.DisposeOfStateObjects)
+ {
+ IDisposable disp = _state as IDisposable;
+ if (null != disp)
+ {
+ disp.Dispose();
+ _state = null;
+ }
+ }
+ }
+
+ public void Abort()
+ {
+ lock (this)
+ {
+ if(currentThread != null)
+ currentThread.Abort();
+ }
+ }
+ }
+ #endregion
+}
--
cgit v1.1