|
3 | 3 | using System.Collections.Generic;
|
4 | 4 | using System.Text;
|
5 | 5 | using System.Threading;
|
| 6 | +using System.Threading.Tasks; |
6 | 7 | using Imazen.Common.Extensibility.ClassicDiskCache;
|
7 | 8 | using Imazen.Common.Issues;
|
8 | 9 | using Microsoft.Extensions.Logging;
|
9 | 10 |
|
10 | 11 | namespace Imazen.DiskCache {
|
11 | 12 |
|
12 |
| - |
| 13 | + internal static class TaskExtensions |
| 14 | + { |
| 15 | + // Allocate the async/await state machine only when needed for performance reason. |
| 16 | + // More info about the state machine: https://blogs.msdn.microsoft.com/seteplia/2017/11/30/dissecting-the-async-methods-in-c/ |
| 17 | + static async Task ForgetAwaited(Task task) |
| 18 | + { |
| 19 | + try |
| 20 | + { |
| 21 | + // No need to resume on the original SynchronizationContext, so use ConfigureAwait(false) |
| 22 | + await task.ConfigureAwait(false); |
| 23 | + } |
| 24 | + catch |
| 25 | + { |
| 26 | + // Nothing to do here |
| 27 | + } |
| 28 | + } |
| 29 | + public static void Forget(this Task task) |
| 30 | + { |
| 31 | + // note: this code is inspired by a tweet from Ben Adams: https://twitter.com/ben_a_adams/status/1045060828700037125 |
| 32 | + // Only care about tasks that may fault (not completed) or are faulted, |
| 33 | + // so fast-path for SuccessfullyCompleted and Canceled tasks. |
| 34 | + if (!task.IsCompleted || task.IsFaulted) |
| 35 | + { |
| 36 | + // use "_" (Discard operation) to remove the warning IDE0058: Because this call is not awaited, execution of the current method continues before the call is completed |
| 37 | + // https://docs.microsoft.com/en-us/dotnet/csharp/discards#a-standalone-discard |
| 38 | + _ = ForgetAwaited(task); |
| 39 | + } |
| 40 | + } |
| 41 | + } |
| 42 | + |
13 | 43 | internal class CleanupManager:IIssueProvider, IDisposable {
|
14 | 44 | private readonly ICleanableCache cache = null;
|
15 | 45 | private readonly CleanupStrategy cs = null;
|
@@ -81,10 +111,17 @@ public void CleanAll() {
|
81 | 111 | public void UsedFile(string relativePath, string physicalPath) {
|
82 | 112 | //Bump the date in memory
|
83 | 113 | cache.Index.bumpDateIfExists(relativePath);
|
84 |
| - //Make sure the 'flush' job for the file is in the queue somewhere, so the access date will get written to disk. |
85 |
| - queue.QueueIfUnique(new CleanupWorkItem(CleanupWorkItem.Kind.FlushAccessedDate, relativePath, physicalPath)); |
86 |
| - //In case it's paused |
87 |
| - worker.MayHaveWork(); |
| 114 | + |
| 115 | + Task.Run(async () => |
| 116 | + { |
| 117 | + // Wait 10 seconds to give the reader thread time to open the file first. |
| 118 | + await Task.Delay(10000); |
| 119 | + //Make sure the 'flush' job for the file is in the queue somewhere, so the access date will get written to disk. |
| 120 | + queue.QueueIfUnique(new CleanupWorkItem(CleanupWorkItem.Kind.FlushAccessedDate, relativePath, |
| 121 | + physicalPath)); |
| 122 | + //In case it's paused |
| 123 | + worker.MayHaveWork(); |
| 124 | + }).Forget(); |
88 | 125 | }
|
89 | 126 |
|
90 | 127 |
|
|
0 commit comments