예제 #1
0
        public void CancelSender(TheThing myBaseThingForLogging, CancellationToken?masterToken = null, bool triggerCancelOnly = false)
        {
            StopThingMatcher();
            SenderTaskInfo previousTaskInfo = null;

            if (pendingHistoryLoops.TryGetValue(cdeMID, out previousTaskInfo))
            {
                try
                {
                    if (!masterToken.HasValue)
                    {
                        masterToken = TheBaseAssets.MasterSwitchCancelationToken;
                    }
                    try
                    {
                        previousTaskInfo.cancelSource.Cancel();
                    }
                    catch { }
                    if (triggerCancelOnly)
                    {
                        return;
                    }
                    int       count       = 0;
                    const int timePerLoop = 1000;
                    const int timeout     = 1 * 60;
                    while (!masterToken.Value.IsCancellationRequested &&
                           previousTaskInfo.task.Status != TaskStatus.Canceled &&
                           previousTaskInfo.task.Status != TaskStatus.Faulted &&
                           previousTaskInfo.task.Status != TaskStatus.RanToCompletion &&
                           count < timeout
                           )
                    {
                        try
                        {
                            previousTaskInfo.task.Wait(timePerLoop, masterToken.Value);
                        }
                        catch (OperationCanceledException) { }
                        count++;
                        if (count >= timeout)
                        {
                            TheBaseAssets.MySYSLOG.WriteToLog(95275, TSM.L(eDEBUG_LEVELS.OFF) ? null : new TSM(myBaseThingForLogging.EngineName, "Connect", eMsgLevel.l2_Warning, $"Waiting on cancel previous send loop for {myBaseThingForLogging.FriendlyName} - {cdeMID}: timeout after {count * timePerLoop} ms. Retrying."));
                            count = 0;
                        }
                    }
                    if (count >= timeout)
                    {
                        TheBaseAssets.MySYSLOG.WriteToLog(95275, TSM.L(eDEBUG_LEVELS.OFF) ? null : new TSM(myBaseThingForLogging.EngineName, "Connect", eMsgLevel.l2_Warning, $"Unable to cancel previous send loop for {myBaseThingForLogging.FriendlyName} - {cdeMID}: timeout after {count * timePerLoop} ms"));
                    }
                    previousTaskInfo.cancelSource?.Dispose();
                    pendingHistoryLoops.RemoveNoCare(cdeMID);
                }
                catch (Exception e)
                {
                    TheBaseAssets.MySYSLOG.WriteToLog(95257, TSM.L(eDEBUG_LEVELS.OFF) ? null : new TSM(myBaseThingForLogging.EngineName, "Connect", eMsgLevel.l6_Debug, String.Format("Exception while cancelling previous send loop for thing {0}: {1}", cdeMID, TheCommonUtils.GetAggregateExceptionMessage(e))));
                }
            }
        }
예제 #2
0
        public bool StartSender(TheThing myBaseThing, TheSenderThing senderClone, Func <object, Task> senderLoop, CancellationToken masterToken)
        {
            if (pendingHistoryLoops.TryGetValue(cdeMID, out var previousTaskInfo))
            {
                if (previousTaskInfo.senderThing.HistoryToken == this.HistoryToken && previousTaskInfo.senderThing.IsEqual(this) && previousTaskInfo.senderThing.IsHistoryTokenCurrent() && !previousTaskInfo.task.IsCompleted && !previousTaskInfo.cancelSource.IsCancellationRequested)
                {
                    return(true);
                }
            }
            CancelSender(myBaseThing, masterToken);
            var cancelTokenSource = CancellationTokenSource.CreateLinkedTokenSource(masterToken, TheBaseAssets.MasterSwitchCancelationToken);
            var senderTaskInfo    = new SenderTaskInfo {
                owner = myBaseThing, senderThing = senderClone, cancelSource = cancelTokenSource
            };
            var task = TheCommonUtils.cdeRunTaskChainAsync("HistorySenderLoop", senderLoop, senderTaskInfo, true);

            //var task = senderLoop(senderTaskInfo);

            senderTaskInfo.task = task;
            pendingHistoryLoops[this.cdeMID] = senderTaskInfo;
            return(true);
        }