예제 #1
0
        static async Task ReplaceFileAsync(FileInfo fileInfo, string newFile, CancellationToken cancellationToken)
        {
            var fullName = fileInfo.FullName;

            var backupFileName = fullName + ".bak";

            File.Delete(backupFileName);

            File.Replace(newFile, fullName, backupFileName);

            for (var retry = 0; ; ++retry)
            {
                if (retry > 0)
                {
                    await Delays.LongDelay(TimeSpan.FromMilliseconds(100 << retry), cancellationToken).ConfigureAwait(false);
                }

                try
                {
                    File.Delete(backupFileName);
                    break;
                }
                catch (IOException ex)
                {
                    if (retry >= 4)
                    {
                        throw;
                    }

                    Debug.WriteLine($"Unable to delete backup file {backupFileName}: {ex.Message}");
                }
            }
        }
예제 #2
0
        public Task <DirectoryInfo> GetDirectoryAsync(DirectoryInfo parentDirectory)
        {
            for (; ;)
            {
                if (_tempDirs.TryGetValue(parentDirectory.FullName, out var directoryInfoTask))
                {
                    return(directoryInfoTask);
                }

                var task = new Task <Task <DirectoryInfo> >(
                    async() =>
                {
                    for (var retry = 0; ; ++retry)
                    {
                        var path = Path.Combine(parentDirectory.FullName, "temp-" + Path.GetRandomFileName());

                        var directoryInfo = new DirectoryInfo(path);

                        if (directoryInfo.Exists)
                        {
                            return(directoryInfo);
                        }

                        if (retry > 0)
                        {
                            await Delays.LongDelay(TimeSpan.FromMilliseconds(50 << retry), CancellationToken.None).ConfigureAwait(false);
                        }

                        try
                        {
                            directoryInfo.Create();

                            return(directoryInfo);
                        }
                        catch (IOException ex)
                        {
                            if (retry >= 4)
                            {
                                throw;
                            }

                            Debug.WriteLine($"Unable to create temp directory {path}, retrying: {ex.Message}");
                        }
                    }
                });

                if (_tempDirs.TryAdd(parentDirectory.FullName, task.Unwrap()))
                {
                    task.Start();

                    return(task.Unwrap());
                }
            }
        }
예제 #3
0
        public void Dispose()
        {
            var cleanupTasks = new List <Task>(_tempDirs.Count);

            foreach (var dirTask in _tempDirs.Values)
            {
                if (dirTask.IsFaulted || dirTask.IsCanceled)
                {
                    var ex = dirTask.Exception;

                    if (null != ex)
                    {
                        Debug.WriteLine("Directory cleanup failed: " + ex.Message);
                    }

                    continue;
                }

                var cleanupTask = dirTask.ContinueWith(
                    async t =>
                {
                    if (t.IsFaulted)
                    {
                        var ex = t.Exception;

                        if (null != ex)
                        {
                            Debug.WriteLine("Directory cleanup failed: " + ex.Message);
                        }

                        return;
                    }

                    var directoryInfo = t.Result;

                    for (var retry = 0; retry < 5; ++retry)
                    {
                        if (retry > 0)
                        {
                            await Delays.LongDelay(TimeSpan.FromMilliseconds(100 << retry), CancellationToken.None).ConfigureAwait(false);
                        }

                        try
                        {
                            directoryInfo.Refresh();

                            if (directoryInfo.Exists)
                            {
                                directoryInfo.Delete(true);
                            }
                        }
                        catch (IOException ex)
                        {
                            if (retry >= 4)
                            {
                                throw;
                            }

                            Debug.WriteLine("Directory cleanup of {0} failed, retrying: {1}", directoryInfo.FullName, ex.Message);
                        }
                    }
                }, TaskContinuationOptions.RunContinuationsAsynchronously);

                cleanupTasks.Add(cleanupTask);
            }

            try
            {
                Task.WaitAll(cleanupTasks.ToArray());
            }
            catch (Exception ex)
            {
                Debug.WriteLine("Directory cleanup failed: " + ex.Message);
            }
        }