Skip to content

Commit 35b512b

Browse files
gave92lukeblevins
andauthored
Cancel previous watcher (#1048)
* Cancel previous watcher * Prevent Duplicate Execution of CloseWatcher() Co-authored-by: Luke Blevins <[email protected]>
1 parent 23e519f commit 35b512b

File tree

2 files changed

+40
-29
lines changed

2 files changed

+40
-29
lines changed

Files/Helpers/NativeDirectoryChangesHelper.cs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,9 @@ public class NativeDirectoryChangesHelper
2020
[DllImport("api-ms-win-core-io-l1-1-1.dll")]
2121
public static extern bool CancelIo(IntPtr hFile);
2222

23+
[DllImport("api-ms-win-core-io-l1-1-1.dll")]
24+
public static extern bool CancelIoEx(IntPtr hFile, IntPtr lpOverlapped);
25+
2326
[DllImport("api-ms-win-core-synch-l1-2-0.dll")]
2427
public static extern uint WaitForMultipleObjectsEx(uint nCount, IntPtr[] lpHandles, bool bWaitAll, uint dwMilliseconds, bool bAlertable);
2528

Files/View Models/ItemViewModel.cs

Lines changed: 37 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@
22
using Files.Common;
33
using Files.Enums;
44
using Files.Helpers;
5-
using Files.Interacts;
65
using Files.Views.Pages;
76
using Microsoft.Toolkit.Uwp.UI;
87
using System;
@@ -20,7 +19,6 @@
2019
using Windows.Foundation.Collections;
2120
using Windows.Storage;
2221
using Windows.Storage.FileProperties;
23-
using Windows.Storage.Search;
2422
using Windows.UI.Core;
2523
using Windows.UI.Text;
2624
using Windows.UI.Xaml;
@@ -367,15 +365,8 @@ private void WorkingDirectoryChanged()
367365

368366
public void CancelLoadAndClearFiles()
369367
{
370-
if(aWatcherAction != null)
371-
{
372-
aWatcherAction?.Cancel();
373-
374-
if (aWatcherAction.Status != AsyncStatus.Started)
375-
{
376-
CloseWatcher();
377-
}
378-
}
368+
Debug.WriteLine("CancelLoadAndClearFiles");
369+
CloseWatcher();
379370

380371
App.CurrentInstance.NavigationToolbar.CanRefresh = true;
381372
if (IsLoadingItems == false) { return; }
@@ -669,8 +660,19 @@ public async void RapidAddItemsToCollectionAsync(string path)
669660

670661
public void CloseWatcher()
671662
{
672-
CancelIo(hWatchDir);
673-
//CloseHandle(hWatchDir);
663+
if (aWatcherAction != null)
664+
{
665+
aWatcherAction?.Cancel();
666+
667+
if (aWatcherAction.Status != AsyncStatus.Started)
668+
{
669+
aWatcherAction = null; // Prevent duplicate execution of this block
670+
Debug.WriteLine("watcher canceled");
671+
CancelIoEx(hWatchDir, IntPtr.Zero);
672+
Debug.WriteLine("watcher handle closed");
673+
CloseHandle(hWatchDir);
674+
}
675+
}
674676
}
675677

676678
public async Task EnumerateItemsFromSpecialFolder(string path)
@@ -857,15 +859,15 @@ public async Task EnumerateItemsFromStandardFolder(string path)
857859

858860
private void WatchForDirectoryChanges(string path)
859861
{
860-
862+
Debug.WriteLine("WatchForDirectoryChanges: {0}", path);
861863
hWatchDir = CreateFileFromApp(path, 1, 1 | 2 | 4,
862864
IntPtr.Zero, 3, (uint)File_Attributes.BackupSemantics | (uint)File_Attributes.Overlapped, IntPtr.Zero);
863865

864866
byte[] buff = new byte[4096];
865867

866868
aWatcherAction = Windows.System.Threading.ThreadPool.RunAsync((x) =>
867869
{
868-
870+
var rand = Guid.NewGuid();
869871
buff = new byte[4096];
870872
int notifyFilters = FILE_NOTIFY_CHANGE_DIR_NAME | FILE_NOTIFY_CHANGE_FILE_NAME;
871873

@@ -880,20 +882,22 @@ private void WatchForDirectoryChanges(string path)
880882
fixed (byte* pBuff = buff)
881883
{
882884
ref var notifyInformation = ref Unsafe.As<byte, FILE_NOTIFY_INFORMATION>(ref buff[0]);
883-
if (x.Status != AsyncStatus.Canceled)
884-
{
885-
NativeDirectoryChangesHelper.ReadDirectoryChangesW(hWatchDir, pBuff,
886-
4096, false,
887-
notifyFilters, null,
888-
ref overlapped, null);
885+
if (x.Status != AsyncStatus.Canceled)
886+
{
887+
NativeDirectoryChangesHelper.ReadDirectoryChangesW(hWatchDir, pBuff,
888+
4096, false,
889+
notifyFilters, null,
890+
ref overlapped, null);
889891
}
890892
else
891893
{
892-
return;
894+
break;
893895
}
894896

895-
if (x.Status == AsyncStatus.Canceled) { return; }
897+
Debug.WriteLine("waiting: {0}", rand);
898+
if (x.Status == AsyncStatus.Canceled) { break; }
896899
var rc = WaitForSingleObjectEx(overlapped.hEvent, INFINITE, true);
900+
Debug.WriteLine("wait done: {0}", rand);
897901

898902
const uint FILE_ACTION_ADDED = 0x00000001;
899903
const uint FILE_ACTION_REMOVED = 0x00000002;
@@ -903,7 +907,7 @@ private void WatchForDirectoryChanges(string path)
903907

904908
uint offset = 0;
905909
ref var notifyInfo = ref Unsafe.As<byte, FILE_NOTIFY_INFORMATION>(ref buff[offset]);
906-
if (x.Status == AsyncStatus.Canceled) { return; }
910+
if (x.Status == AsyncStatus.Canceled) { break; }
907911

908912
do
909913
{
@@ -919,6 +923,7 @@ private void WatchForDirectoryChanges(string path)
919923

920924
uint action = notifyInfo.Action;
921925

926+
Debug.WriteLine("action: {0}", action);
922927
switch (action)
923928
{
924929
case FILE_ACTION_ADDED:
@@ -949,14 +954,16 @@ private void WatchForDirectoryChanges(string path)
949954

950955
} while (notifyInfo.NextEntryOffset != 0 && x.Status != AsyncStatus.Canceled);
951956

952-
//ResetEvent(overlapped.hEvent);
953-
Debug.WriteLine("\n\nTask running...\n\n");
957+
//ResetEvent(overlapped.hEvent);
958+
Debug.WriteLine("Task running...");
954959
}
955960
}
956961
}
962+
CloseHandle(overlapped.hEvent);
963+
Debug.WriteLine("aWatcherAction done: {0}", rand);
957964
});
958965

959-
Debug.WriteLine("\n\nTask exiting...\n\n");
966+
Debug.WriteLine("Task exiting...");
960967
}
961968

962969
public void AddFileOrFolder(ListedItem item)
@@ -1154,7 +1161,7 @@ private async Task AddFolder(StorageFolder folder)
11541161
IsLoadingItems = false;
11551162
return;
11561163
}
1157-
1164+
11581165
_filesAndFolders.Add(new ListedItem(folder.FolderRelativeId)
11591166
{
11601167
//FolderTooltipText = tooltipString,
@@ -1278,6 +1285,7 @@ public void Dispose()
12781285
{
12791286
_addFilesCTS?.Dispose();
12801287
_semaphoreCTS?.Dispose();
1288+
CloseWatcher();
12811289
}
12821290
}
1283-
}
1291+
}

0 commit comments

Comments
 (0)