private async Task ZInvokeAndWaitAsync(EventArgs pEventArgs, cTrace.cContext pParentContext) { var lContext = pParentContext.NewMethod(nameof(cCallbackSynchroniser), nameof(ZInvokeAndWaitAsync)); var lSynchronizationContext = SynchronizationContext; if (lSynchronizationContext == null || ReferenceEquals(SynchronizationContext.Current, lSynchronizationContext)) { lContext.TraceVerbose("on the correct sc"); mInvokes.Enqueue(new sInvoke(pEventArgs)); ZInvokeWorker(lContext); return; } lContext.TraceVerbose("not on the correct sc"); using (var lReleaser = new cReleaser("invokesynchroniser_fireandwait", mCancellationTokenSource.Token)) { mInvokes.Enqueue(new sInvoke(pEventArgs, lReleaser)); // in case this object is blocking the SC (in 'wait' above), do a release to let it invoke the event handlers mForegroundReleaser.Release(lContext); // we use a background task to post to the sc in case; // 1) the sc doesn't implement an async post method and // 2) it is the sc that we are blocking OR ARE ABOUT TO BLOCK // note the words in capitals - at this very moment we may be being entered by the SC and are about to block it // (and in that case the 'wait' will do the event delivery because of the 'release' we just did above) // mBackgroundReleaser.Release(lContext); lContext.TraceVerbose("waiting for the invoke to be done"); await lReleaser.GetAwaitReleaseTask(lContext).ConfigureAwait(false); } }
public cCallbackSynchroniser(object pSender, cTrace.cContext pParentContext) { var lContext = pParentContext.NewObject(nameof(cCallbackSynchroniser)); mSender = pSender; mForegroundReleaser = new cReleaser("callbacksynchroniser_foreground", mCancellationTokenSource.Token); mBackgroundReleaser = new cReleaser("callbacksynchroniser_background", mCancellationTokenSource.Token); mBackgroundTask = ZBackgroundTaskAsync(lContext); }
public cCommandPipeline(cCallbackSynchroniser pSynchroniser, Action <cTrace.cContext> pDisconnected, cBatchSizerConfiguration pNetworkWriteConfiguration, cIdleConfiguration pIdleConfiguration, cTrace.cContext pParentContext) { var lContext = pParentContext.NewObject(nameof(cCommandPipeline), pIdleConfiguration); mSynchroniser = pSynchroniser ?? throw new ArgumentNullException(nameof(pSynchroniser)); mDisconnected = pDisconnected ?? throw new ArgumentNullException(nameof(pDisconnected)); if (pNetworkWriteConfiguration == null) { throw new ArgumentNullException(nameof(pNetworkWriteConfiguration)); } mConnection = new cConnection(pNetworkWriteConfiguration); mIdleConfiguration = pIdleConfiguration; mResponseTextProcessor = new cResponseTextProcessor(pSynchroniser); // these depend on the cancellationtokensource being constructed mBackgroundReleaser = new cReleaser("commandpipeline_background", mBackgroundCancellationTokenSource.Token); mBackgroundAwaiter = new cAwaiter(mBackgroundCancellationTokenSource.Token); mBackgroundSendBuffer = new cSendBuffer(pSynchroniser, mConnection, mBackgroundCancellationTokenSource.Token); // plumbing mIdleBlock.Released += mBackgroundReleaser.Release; // when the idle block is removed, kick the background process }
public sInvoke(EventArgs pEventArgs, cReleaser pReleaser) { EventArgs = pEventArgs; Releaser = pReleaser; }
public sInvoke(EventArgs pEventArgs) { EventArgs = pEventArgs; Releaser = null; }