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);
            }
Exemple #3
0
                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;
 }