/**/
        private static readonly ConditionalWeakTable <SemaphoreSlim, SemaphoreSlimCalledWrapper>
        CalledWrappers = new ConditionalWeakTable <SemaphoreSlim, SemaphoreSlimCalledWrapper>();

        public static SemaphoreSlimCalledWrapper GetCalledWrapper(
            this SemaphoreSlim lockSem
            )
        {
            Assert.NotNull(lockSem);
            return(CalledWrappers.GetValue(
                       lockSem,
                       _ => new SemaphoreSlimCalledWrapper(lockSem)
                       ));
        }

        /**/
        public static async Task <IDisposable> GetDisposable(
            this SemaphoreSlim lockSemaphoreSlim,
            bool throwCancelledIfSemLocked     = false,
            CancellationToken token            = default(CancellationToken),
            [CallerMemberName] string mthdName = "",
            [CallerLineNumber] int lineNum     = 0,
#if DEBUG
            [CallerFilePath]
#endif
            string fp = ""
            )
        {
            int fc = MiscFuncs.CheckStackFrameCount();

            if (
                throwCancelledIfSemLocked &&
                lockSemaphoreSlim.CurrentCount == 0
                )
            {
                throw new OperationCanceledException();
            }
            return(await SemaphoreSlimDisposableWrapper
                   .CreateInstance(
                       lockSemaphoreSlim,
                       $"{fc} {mthdName} line {lineNum} file {fp}",
                       token
                       ).ConfigureAwait(false));
        }
        public static async Task <SemaphoreSlimDisposableWrapper> CreateInstance(
            SemaphoreSlim lockSem,
            string mthdName,
            CancellationToken token
            )
        {
            if (lockSem == null)
            {
                throw new ArgumentNullException(
                          MyNameof.GetLocalVarName(() => lockSem)
                          );
            }
            var wrapperNum = Interlocked.Increment(ref _nextDbNum);
            var result     = new SemaphoreSlimDisposableWrapper(lockSem);

            result._wrapperNum  = wrapperNum;
            result.MthdName     = mthdName;
            result.TryEnterTime = DateTime.UtcNow;
            SemWrappersDb.TryAdd(wrapperNum, result);
            await result._lockSem.WaitAsync(token).ConfigureAwait(false);

            result.EnterTime = DateTime.UtcNow;
            return(result);
        }