示例#1
0
        /// <summary>
        /// Wrap all IO operations on setting files with this function to avoid file-in-use errors
        /// </summary>
        private void ExecuteSynchronized(Action ioOperation)
        {
            var fileName = _fileSystem.GetFullPath(_fileName);

            // Global: ensure mutex is honored across TS sessions
            using (var mutex = new Mutex(false, "Global\\" + MutexNamingHelper.GenerateUniqueToken(fileName)))
            {
                var owner = false;
                try
                {
                    // operations on NuGet.config should be very short lived
                    owner = mutex.WaitOne(TimeSpan.FromMinutes(1));
                    // decision here is to proceed even if we were not able to get mutex ownership
                    // and let the potential IO errors bubble up. Reasoning is that failure to get
                    // ownership probably means faulty hardware and in this case it's better to report
                    // back than hang
                    ioOperation();
                }
                finally
                {
                    if (owner)
                    {
                        mutex.ReleaseMutex();
                    }
                }
            }
        }
示例#2
0
        /// <remarks>
        /// We use this method instead of the "safe" methods in FileSystem because it attempts to retry multiple times with delays.
        /// In our case, if we are unable to perform IO over the machine cache, we want to quit trying immediately.
        /// </remarks>
        private bool TryAct(Func <bool> action, string path)
        {
            try
            {
                // Global: machine cache is per user across TS sessions
                var mutexName = "Global\\" + MutexNamingHelper.GenerateUniqueToken(FileSystem.GetFullPath(path) ?? path);
                using (var mutex = new Mutex(false, mutexName))
                {
                    bool owner = false;
                    try
                    {
                        try
                        {
                            owner = mutex.WaitOne(TimeSpan.FromMinutes(3));
                            // ideally we should throw an exception here if !owner such as
                            // throw new TimeoutException(string.Format("Timeout waiting for Machine Cache mutex for {0}", fullPath));
                            // we decided against it: machine cache operations being "best effort" basis.
                            // this may cause "File in use" exceptions for long lasting operations such as downloading a large package on
                            // a slow network connection
                        }
                        catch (AbandonedMutexException)
                        {
                            // TODO: consider logging a warning; abandonning a mutex is an indication something wrong is going on
                            owner = true; // now mine
                        }

                        return(action());
                    }
                    finally
                    {
                        if (owner)
                        {
                            mutex.ReleaseMutex();
                        }
                    }
                }
            }
            catch (IOException)
            {
            }
            catch (UnauthorizedAccessException)
            {
                // Do nothing if this fails.
            }
            return(false);
        }