/// <summary> /// Post or send a delegate to the thread that /// is defined as using the synContext that is passed into the Task ctor /// in order for that the delegate event can be raised on the correct thread /// </summary> /// <param name="isPost">is the call a non-blocking post(true) or a blocking send(false)</param> /// <param name="handler">event handler that will be called on the thread defined by synContext</param> /// <param name="args">arguments for delegate call</param> protected void PostOrSend(Boolean isPost, Delegate handler, object[] args) { //return if null if (this.syncContext == null) { return; } //create eventArgs that hold information about the call ProcessAsyncEventArgs paea = new ProcessAsyncEventArgs(this, handler, args); if (isPost == false) { //throw here if trying to send to same thread if (this.syncContext == SynchronizationContext.Current) { throw new InvalidOperationException("Cannot use send to same thread, use post or SyncNotify event"); } this.syncContext.Send(this.asyncHandler, paea); } else { this.syncContext.Post(this.asyncHandler, paea); } }
/// <summary> /// raise an event defined by a ProcessAsyncEventArgs. /// The event is raised on the thread that is making the RaiseEvent() call /// </summary> /// <param name="paea">args that contain all the infomation about event to be raised</param> private static void RaiseEvent(ProcessAsyncEventArgs paea) { //try to cast to known types of handler since those are faster than a DynamicInvoke //in most cases the handler is either a TaskStatusEventHandler or a SendOrPostCallback //but throw in a few extras that we know about if (paea.Handler is FluidTrade.Reporting.TaskStatusEventHandler) { ((TaskStatusEventHandler)paea.Handler)(paea.Sender, (TaskStatusEventArgs)paea.Args[1]); } else if (paea.Handler is System.Threading.SendOrPostCallback) { ((System.Threading.SendOrPostCallback)paea.Handler)(paea.Args[0]); } else if (paea.Handler is EventHandler) { //event handler is if ((paea.Args == null) || (paea.Args.Length < 1)) { ((EventHandler)paea.Handler)(paea.Sender, EventArgs.Empty); } else { ((EventHandler)paea.Handler)(paea.Sender, (EventArgs)paea.Args[0]); } } else if (paea.Handler is MethodInvoker) { ((MethodInvoker)paea.Handler)(); } else if (paea.Handler is WaitCallback) { ((WaitCallback)paea.Handler)(paea.Args[0]); } else { paea.RetVal = paea.Handler.DynamicInvoke(paea.Args); } }