A global Mutex is not only to ensure to have only one instance of an application. I personally prefer using Microsoft.VisualBasic to ensure single instance application like described in What is the correct way to create a single-instance WPF application? (Dale Ragan answer)... I found that's easier to pass arguments received on new application startup to the initial single instance application.
But regarding some previous code in this thread, I would prefer to not create a Mutex each time I want to have a lock on it. It could be fine for a single instance application but in other usage it appears to me has overkill.
That's why I suggest this implementation instead:
Usage:
static MutexGlobal _globalMutex = null;
static MutexGlobal GlobalMutexAccessEMTP
{
    get
    {
        if (_globalMutex == null)
        {
            _globalMutex = new MutexGlobal();
        }
        return _globalMutex;
    }
}
using (GlobalMutexAccessEMTP.GetAwaiter())
{
    ...
}   
Mutex Global Wrapper:
using System;
using System.Reflection;
using System.Runtime.InteropServices;
using System.Security.AccessControl;
using System.Security.Principal;
using System.Threading;
namespace HQ.Util.General.Threading
{
    public class MutexGlobal : IDisposable
    {
        // ************************************************************************
        public string Name { get; private set; }
        internal Mutex Mutex { get; private set; }
        public int DefaultTimeOut { get; set; }
        public Func<int, bool> FuncTimeOutRetry { get; set; }
        // ************************************************************************
        public static MutexGlobal GetApplicationMutex(int defaultTimeOut = Timeout.Infinite)
        {
            return new MutexGlobal(defaultTimeOut, ((GuidAttribute)Assembly.GetExecutingAssembly().GetCustomAttributes(typeof(GuidAttribute), false).GetValue(0)).Value);
        }
        // ************************************************************************
        public MutexGlobal(int defaultTimeOut = Timeout.Infinite, string specificName = null)
        {
            try
            {
                if (string.IsNullOrEmpty(specificName))
                {
                    Name = Guid.NewGuid().ToString();
                }
                else
                {
                    Name = specificName;
                }
                Name = string.Format("Global\\{{{0}}}", Name);
                DefaultTimeOut = defaultTimeOut;
                FuncTimeOutRetry = DefaultFuncTimeOutRetry;
                var allowEveryoneRule = new MutexAccessRule(new SecurityIdentifier(WellKnownSidType.WorldSid, null), MutexRights.FullControl, AccessControlType.Allow);
                var securitySettings = new MutexSecurity();
                securitySettings.AddAccessRule(allowEveryoneRule);
                Mutex = new Mutex(false, Name, out bool createdNew, securitySettings);
                if (Mutex == null)
                {
                    throw new Exception($"Unable to create mutex: {Name}");
                }
            }
            catch (Exception ex)
            {
                Log.Log.Instance.AddEntry(Log.LogType.LogException, $"Unable to create Mutex: {Name}", ex);
                throw;
            }
        }
        // ************************************************************************
        /// <summary>
        /// 
        /// </summary>
        /// <param name="timeOut"></param>
        /// <returns></returns>
        public MutexGlobalAwaiter GetAwaiter(int timeOut)
        {
            return new MutexGlobalAwaiter(this, timeOut);
        }
        // ************************************************************************
        /// <summary>
        /// 
        /// </summary>
        /// <param name="timeOut"></param>
        /// <returns></returns>
        public MutexGlobalAwaiter GetAwaiter()
        {
            return new MutexGlobalAwaiter(this, DefaultTimeOut);
        }
        // ************************************************************************
        /// <summary>
        /// This method could either throw any user specific exception or return 
        /// true to retry. Otherwise, retruning false will let the thread continue
        /// and you should verify the state of MutexGlobalAwaiter.HasTimedOut to 
        /// take proper action depending on timeout or not. 
        /// </summary>
        /// <param name="timeOutUsed"></param>
        /// <returns></returns>
        private bool DefaultFuncTimeOutRetry(int timeOutUsed)
        {
            // throw new TimeoutException($"Mutex {Name} timed out {timeOutUsed}.");
            Log.Log.Instance.AddEntry(Log.LogType.LogWarning, $"Mutex {Name} timeout: {timeOutUsed}.");
            return true; // retry
        }
        // ************************************************************************
        public void Dispose()
        {
            if (Mutex != null)
            {
                Mutex.ReleaseMutex();
                Mutex.Close();
            }
        }
        // ************************************************************************
    }
}
Awaiter
using System;
namespace HQ.Util.General.Threading
{
    public class MutexGlobalAwaiter : IDisposable
    {
        MutexGlobal _mutexGlobal = null;
        public bool HasTimedOut { get; set; } = false;
        internal MutexGlobalAwaiter(MutexGlobal mutexEx, int timeOut)
        {
            _mutexGlobal = mutexEx;
            do
            {
                HasTimedOut = !_mutexGlobal.Mutex.WaitOne(timeOut, false);
                if (! HasTimedOut) // Signal received
                {
                    return;
                }
            } while (_mutexGlobal.FuncTimeOutRetry(timeOut));
        }
        #region IDisposable Support
        private bool disposedValue = false; // To detect redundant calls
        protected virtual void Dispose(bool disposing)
        {
            if (!disposedValue)
            {
                if (disposing)
                {
                    _mutexGlobal.Mutex.ReleaseMutex();
                }
                // TODO: free unmanaged resources (unmanaged objects) and override a finalizer below.
                // TODO: set large fields to null.
                disposedValue = true;
            }
        }
        // TODO: override a finalizer only if Dispose(bool disposing) above has code to free unmanaged resources.
        // ~MutexExAwaiter()
        // {
        //   // Do not change this code. Put cleanup code in Dispose(bool disposing) above.
        //   Dispose(false);
        // }
        // This code added to correctly implement the disposable pattern.
        public void Dispose()
        {
            // Do not change this code. Put cleanup code in Dispose(bool disposing) above.
            Dispose(true);
            // TODO: uncomment the following line if the finalizer is overridden above.
            // GC.SuppressFinalize(this);
        }
        #endregion
    }
}