public override void Execute(Sonic.Net.ThreadPool tp) { AsyncDelegate ad = this.UserObject as AsyncDelegate; if (ad != null) { try { ad(); } catch (Exception ex) { _exception = ex; } try { if (_asyncTaskCompleted != null) { _asyncTaskCompleted(); } } catch (Exception exInner) { _executionCompletionDelegateException = exInner; } } this._ev.Set(); }
/// <summary> /// Initializes the AppDomain wide ManagedIOCP ThreadPool /// used by async object execution /// </summary> public static void Open() { lock (typeof(Async)) { if (s_AsyncCodeDelegateTP == null) { s_AsyncCodeDelegateTP = new Sonic.Net.ThreadPool(1, 1); } } }
protected void Initialize(AsyncDelegate ad, Sonic.Net.ThreadPool tp, Async[] arrDependentOnAsync, AsyncCodeBlockExecutionCompleteCallback executionCompleteCallback, bool waitable) { if (ad != null) { _waitable = waitable; _ad = ad; _tp = tp; _targetObject = ad.Target; _targetType = ad.Method.DeclaringType; if (_waitable == false) { AsyncDelegateTask adt = new AsyncDelegateTask(ad); adt.TaskCompleted = this.MarkCompleted; _task = adt; } else { WaitableAsyncDelegateTask wadt = new WaitableAsyncDelegateTask(ad); wadt.TaskCompleted = this.MarkCompleted; _task = wadt; } _executionCompleteCallback = executionCompleteCallback; bool dispatchForExecution = true; if (arrDependentOnAsync != null) { lock (_syncObject) { foreach (Async asyncObj in arrDependentOnAsync) { if (asyncObj.AddToDependencyCodeBlockList(this) == true) { _dependentCount++; } } if (_dependentCount == 0) { dispatchForExecution = true; } else { dispatchForExecution = false; } } } // Store the current SynchronizationContext // _synchronizationContext = SynchronizationContext.Current; if (dispatchForExecution == true) { Execute(ad, _task, tp); } } }
/* * More research is required in the area of serializing and deserializing * async code blocks. Here is the status... * * Pending creation of MSIL for the anonymous method body. * MethodBody.GetILAsByteArray() is only giving the raw IL Opcodes. * Opcodes for code size, maxstacksize and local variable initialization * are missing. Also even if I was able to serialize and deserialize the * IL of the method body somehow, I need to figure out a way to add any * references to the assemblies used by method body, while executing the * deserialized code block * * public static explicit operator SerializableCodeBlock(async objAsync) * { * // Create a SerializableCodeBlock object from async object data * // * SerializableCodeBlock scb = new SerializableCodeBlock(); * if (objAsync._targetType != null) * scb.TypeName = objAsync._targetType.FullName; * else * scb.TypeName = "T" + Guid.NewGuid().ToString().Replace("-", ""); * if (objAsync._targetObject != null) * { * scb.InstanceID = objAsync._targetObject.GetHashCode(); * FieldInfo[] arrFI = objAsync._targetType.GetFields(); * FieldValue[] arrFV = new FieldValue[arrFI.Length]; * int i = 0; * foreach (FieldInfo fi in arrFI) * { * object val = objAsync._targetType.InvokeMember(fi.Name, BindingFlags.GetField, null, objAsync._targetObject, null); * arrFV[i] = new FieldValue(); * arrFV[i].Name = fi.Name; * arrFV[i].Value = val; * i++; * } * scb.FieldValueList = arrFV; * } * scb.MethodName = objAsync._ad.Method.Name; * if (objAsync._tp != null) scb.ThreadPoolID = objAsync._tp.GetHashCode().ToString(); * MethodBody mb = objAsync._ad.Method.GetMethodBody(); * byte[] il = mb.GetILAsByteArray(); * List<byte> codeSizeList = new List<byte>(); * codeSizeList.Add(0x03); * codeSizeList.Add(0x30); * codeSizeList.Add(0x0A); * codeSizeList.Add(0x00); * codeSizeList.Add((byte)il.Length); // code size * codeSizeList.Add(0x00); * codeSizeList.Add(0x00); * codeSizeList.Add(0x00); * codeSizeList.Add(0x00); * codeSizeList.Add(0x00); * codeSizeList.Add(0x00); * codeSizeList.Add(0x00); * codeSizeList.AddRange(il); * scb.MethodIL = codeSizeList.ToArray(); * return scb; * } * */ #endregion #region Private Static Methods private static void Execute(AsyncDelegate ad, ITask task, Sonic.Net.ThreadPool tp) { if (s_AsyncCodeDelegateTP != null) { if (tp == null) { s_AsyncCodeDelegateTP.Dispatch(task); } else { tp.Dispatch(task); } } else { throw new ApplicationException("Thread Pool used by AsynchronousCodeBlock class is closed. " + "Cannot execute any more asynchronous code blocks on default Thread pool. Please open the " + "Thread Pool used by AsynchronousCodeBlock class or supply your own Thread Pool object for " + "asynchronous code block"); } }
/// <summary> /// Creates an instance of waitableasync class, that executes /// the wrapped code block on the developer supplied /// Managed IOCP based ThreadPool /// </summary> /// <param name="ad"> /// Anonymous delegate wrapping the code block to execute /// </param> /// <param name="tp">Managed IOCP based ThreadPool object</param> /// <param name="executionCompleteCallback"> /// Delegate handler that will be called when the execution of the /// code block wrapped by this instance is completed. Dependent /// async objects will be scheduled for execution after the /// completion callback has executed /// </param> public waitableasync(AsyncDelegate ad, Sonic.Net.ThreadPool tp, AsyncCodeBlockExecutionCompleteCallback executionCompleteCallback) : base(ad, tp, executionCompleteCallback) { }
/// <summary> /// Creates an instance of waitableasync class, that executes /// the wrapped code block on the developer supplied /// Managed IOCP based ThreadPool /// </summary> /// <param name="ad"> /// Anonymous delegate wrapping the code block to execute /// </param> /// <param name="tp">Managed IOCP based ThreadPool object</param> public waitableasync(AsyncDelegate ad, Sonic.Net.ThreadPool tp) : base(ad, tp) { }
protected override void Initialize(AsyncDelegate ad, Sonic.Net.ThreadPool tp, Async[] arrDependentOnAsync, AsyncCodeBlockExecutionCompleteCallback executionCompleteCallback) { Initialize(ad, tp, arrDependentOnAsync, executionCompleteCallback, true); }
/// <summary> /// Creates an instance of waitableasync class, that executes /// the wrapped code block on the default AppDomain wide or /// developer supplied Managed IOCP based ThreadPool /// </summary> /// <param name="ad"> /// Anonymous delegate wrapping the code block to execute /// </param> /// <param name="tp">Managed IOCP based ThreadPool object</param> /// <param name="dependentOnAsync"> /// async object array on which the current instance of waitableasync /// depends on. The code wrapped by the current instance /// of waitableasync object will be executed after the code wrapped /// by dependentOnAsync object array has completed execution /// </param> public waitableasync(AsyncDelegate ad, Sonic.Net.ThreadPool tp, Async[] arrDependentOnAsync) : base(ad, tp, arrDependentOnAsync) { }
/// <summary> /// Creates an instance of async class, that executes /// the wrapped code block on the developer supplied /// Managed IOCP based ThreadPool /// </summary> /// <param name="ad"> /// Anonymous delegate wrapping the code block to execute /// </param> /// <param name="tp">Managed IOCP based ThreadPool object</param> public Async(AsyncDelegate ad, Sonic.Net.ThreadPool tp) { Initialize(ad, tp, null, null); }
/// <summary> /// Creates an instance of async class, that executes /// the wrapped code block on the developer supplied /// Managed IOCP based ThreadPool /// </summary> /// <param name="ad"> /// Anonymous delegate wrapping the code block to execute /// </param> /// <param name="tp">Managed IOCP based ThreadPool object</param> /// <param name="dependentOnAsync"> /// async object array on which the current instance of async /// depends on. The code wrapped by the current instance /// of async object will be executed after the code wrapped /// by dependentOnAsync object array has completed execution /// </param> /// <param name="executionCompleteCallback"> /// Delegate handler that will be called when the execution of the /// code block wrapped by this instance is completed. Dependent /// async objects will be scheduled for execution after the /// completion callback has executed /// </param> public Async(AsyncDelegate ad, Sonic.Net.ThreadPool tp, Async[] arrDependentOnAsync, AsyncCodeBlockExecutionCompleteCallback executionCompleteCallback) { Initialize(ad, tp, arrDependentOnAsync, executionCompleteCallback); }
/// <summary> /// Creates an instance of async class, that executes /// the wrapped code block on the developer supplied /// Managed IOCP based ThreadPool /// </summary> /// <param name="ad"> /// Anonymous delegate wrapping the code block to execute /// </param> /// <param name="tp">Managed IOCP based ThreadPool object</param> /// <param name="dependentOnAsync"> /// async object array on which the current instance of async /// depends on. The code wrapped by the current instance /// of async object will be executed after the code wrapped /// by dependentOnAsync object array has completed execution /// </param> public Async(AsyncDelegate ad, Sonic.Net.ThreadPool tp, Async[] arrDependentOnAsync) { Initialize(ad, tp, arrDependentOnAsync, null); }
/// <summary> /// Creates an instance of async class, that executes /// the wrapped code block on the developer supplied /// Managed IOCP based ThreadPool /// </summary> /// <param name="ad"> /// Anonymous delegate wrapping the code block to execute /// </param> /// <param name="tp">Managed IOCP based ThreadPool object</param> /// <param name="dependentOnAsync"> /// async object on which the current instance of async /// depends on. The code wrapped by the current instance /// of async object will be executed after the code wrapped /// by dependentOnAsync object has completed execution /// </param> public Async(AsyncDelegate ad, Sonic.Net.ThreadPool tp, Async dependentOnAsync) { Initialize(ad, tp, new Async[] { dependentOnAsync }, null); }
/// <summary> /// Creates an instance of async class, that executes /// the wrapped code block on the developer supplied /// Managed IOCP based ThreadPool /// </summary> /// <param name="ad"> /// Anonymous delegate wrapping the code block to execute /// </param> /// <param name="tp">Managed IOCP based ThreadPool object</param> /// <param name="executionCompleteCallback"> /// Delegate handler that will be called when the execution of the /// code block wrapped by this instance is completed. Dependent /// async objects will be scheduled for execution after the /// completion callback has executed /// </param> public Async(AsyncDelegate ad, Sonic.Net.ThreadPool tp, AsyncCodeBlockExecutionCompleteCallback executionCompleteCallback) { Initialize(ad, tp, null, executionCompleteCallback); }