public bool TryInvoke <TResult>(Func <LibGit2Repo, TResult> function, out TResult result)
        {
            try
            {
                Interlocked.Increment(ref this.activeCallers);
                LibGit2Repo repo = this.GetSharedRepo();

                if (repo != null)
                {
                    result = function(repo);
                    return(true);
                }

                result = default(TResult);
                return(false);
            }
            catch (Exception e)
            {
                this.tracer.RelatedWarning("Exception while invoking libgit2: " + e.ToString(), Keywords.Telemetry);
                throw;
            }
            finally
            {
                Interlocked.Decrement(ref this.activeCallers);
            }
        }
        public void Dispose()
        {
            this.disposing = true;

            lock (this.sharedRepoLock)
            {
                this.sharedRepo?.Dispose();
                this.sharedRepo = null;
            }
        }
        public void DisposeSharedRepo()
        {
            lock (this.sharedRepoLock)
            {
                if (this.disposing || this.activeCallers > 0)
                {
                    return;
                }

                this.sharedRepo?.Dispose();
                this.sharedRepo = null;
            }
        }
        private LibGit2Repo GetSharedRepo()
        {
            lock (this.sharedRepoLock)
            {
                if (this.disposing)
                {
                    return(null);
                }

                if (this.sharedRepo == null)
                {
                    this.sharedRepo = this.createRepo();
                }

                return(this.sharedRepo);
            }
        }