Skip to content

Commit 23e519f

Browse files
committed
Remove Use of CloseHandle
1 parent 1bf3597 commit 23e519f

File tree

1 file changed

+105
-106
lines changed

1 file changed

+105
-106
lines changed

Files/View Models/ItemViewModel.cs

Lines changed: 105 additions & 106 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
using System.Threading;
1717
using System.Threading.Tasks;
1818
using Windows.ApplicationModel.Core;
19+
using Windows.Foundation;
1920
using Windows.Foundation.Collections;
2021
using Windows.Storage;
2122
using Windows.Storage.FileProperties;
@@ -34,8 +35,10 @@ namespace Files.Filesystem
3435
{
3536
public class ItemViewModel : INotifyPropertyChanged, IDisposable
3637
{
37-
private volatile bool IsWatching = false;
38+
private volatile bool MustTryToWatchAgain = false;
39+
private static SemaphoreSlim semaphoreSlim = new SemaphoreSlim(1, 1);
3840
private IntPtr hWatchDir;
41+
private IAsyncAction aWatcherAction;
3942
public ReadOnlyObservableCollection<ListedItem> FilesAndFolders { get; }
4043
public ListedItem CurrentFolder { get; private set; }
4144
public CollectionViewSource viewSource;
@@ -364,11 +367,16 @@ private void WorkingDirectoryChanged()
364367

365368
public void CancelLoadAndClearFiles()
366369
{
367-
var x = CancelIo(hWatchDir);
368-
CloseHandle(hWatchDir);
369-
hWatchDir = new IntPtr(-1);
370-
Debug.WriteLine("\n\nWatcher task aborted...\n\n"); // Cancel directory item change watcher
371-
IsWatching = false;
370+
if(aWatcherAction != null)
371+
{
372+
aWatcherAction?.Cancel();
373+
374+
if (aWatcherAction.Status != AsyncStatus.Started)
375+
{
376+
CloseWatcher();
377+
}
378+
}
379+
372380
App.CurrentInstance.NavigationToolbar.CanRefresh = true;
373381
if (IsLoadingItems == false) { return; }
374382

@@ -383,12 +391,6 @@ public void CancelLoadAndClearFiles()
383391
}
384392
}
385393

386-
public void CancelChangeWatcher()
387-
{
388-
var x = CancelIo(hWatchDir);
389-
Debug.WriteLine("\n\nWatcher task aborted...\n\n");
390-
}
391-
392394
public void OrderFiles()
393395
{
394396
if (_filesAndFolders.Count == 0)
@@ -632,10 +634,8 @@ public async void RapidAddItemsToCollectionAsync(string path)
632634
{
633635

634636
await EnumerateItemsFromStandardFolder(path);
635-
if (!IsWatching)
636-
{
637-
WatchForDirectoryChanges(path);
638-
}
637+
WatchForDirectoryChanges(path);
638+
639639
}
640640

641641
if (FilesAndFolders.Count == 0)
@@ -667,7 +667,11 @@ public async void RapidAddItemsToCollectionAsync(string path)
667667
}
668668
}
669669

670-
private static SemaphoreSlim semaphoreSlim = new SemaphoreSlim(1, 1);
670+
public void CloseWatcher()
671+
{
672+
CancelIo(hWatchDir);
673+
//CloseHandle(hWatchDir);
674+
}
671675

672676
public async Task EnumerateItemsFromSpecialFolder(string path)
673677
{
@@ -851,113 +855,108 @@ public async Task EnumerateItemsFromStandardFolder(string path)
851855

852856
}
853857

854-
private async void WatchForDirectoryChanges(string path)
858+
private void WatchForDirectoryChanges(string path)
855859
{
856-
var uiThreadScheduler = TaskScheduler.FromCurrentSynchronizationContext();
857-
Task thrItem = null;
858-
IsWatching = true;
860+
859861
hWatchDir = CreateFileFromApp(path, 1, 1 | 2 | 4,
860862
IntPtr.Zero, 3, (uint)File_Attributes.BackupSemantics | (uint)File_Attributes.Overlapped, IntPtr.Zero);
861863

862864
byte[] buff = new byte[4096];
863865

864-
await Windows.System.Threading.ThreadPool.RunAsync((x) =>
865-
{
866-
buff = new byte[4096];
867-
int notifyFilters = FILE_NOTIFY_CHANGE_DIR_NAME | FILE_NOTIFY_CHANGE_FILE_NAME;
866+
aWatcherAction = Windows.System.Threading.ThreadPool.RunAsync((x) =>
867+
{
868868

869-
OVERLAPPED overlapped = new OVERLAPPED();
870-
overlapped.hEvent = CreateEvent(IntPtr.Zero, false, false, null);
871-
const uint INFINITE = 0xFFFFFFFF;
869+
buff = new byte[4096];
870+
int notifyFilters = FILE_NOTIFY_CHANGE_DIR_NAME | FILE_NOTIFY_CHANGE_FILE_NAME;
872871

873-
while (hWatchDir.ToInt64() != -1)
874-
{
875-
876-
unsafe
877-
{
878-
fixed (byte* pBuff = buff)
879-
{
880-
ref var notifyInformation = ref Unsafe.As<byte, FILE_NOTIFY_INFORMATION>(ref buff[0]);
881-
if (hWatchDir.ToInt64() != -1)
872+
OVERLAPPED overlapped = new OVERLAPPED();
873+
overlapped.hEvent = CreateEvent(IntPtr.Zero, false, false, null);
874+
const uint INFINITE = 0xFFFFFFFF;
875+
876+
while (x.Status != AsyncStatus.Canceled)
877+
{
878+
unsafe
879+
{
880+
fixed (byte* pBuff = buff)
881+
{
882+
ref var notifyInformation = ref Unsafe.As<byte, FILE_NOTIFY_INFORMATION>(ref buff[0]);
883+
if (x.Status != AsyncStatus.Canceled)
882884
{
883885
NativeDirectoryChangesHelper.ReadDirectoryChangesW(hWatchDir, pBuff,
884886
4096, false,
885887
notifyFilters, null,
886888
ref overlapped, null);
887-
}
888-
else
889-
{
890-
IsWatching = false;
891-
return;
892-
}
893-
894-
var rc = WaitForSingleObjectEx(overlapped.hEvent, INFINITE, true);
895-
896-
const uint FILE_ACTION_ADDED = 0x00000001;
897-
const uint FILE_ACTION_REMOVED = 0x00000002;
898-
const uint FILE_ACTION_MODIFIED = 0x00000003;
899-
const uint FILE_ACTION_RENAMED_OLD_NAME = 0x00000004;
900-
const uint FILE_ACTION_RENAMED_NEW_NAME = 0x00000005;
901-
902-
uint offset = 0;
903-
ref var notifyInfo = ref Unsafe.As<byte, FILE_NOTIFY_INFORMATION>(ref buff[offset]);
904-
if (hWatchDir.ToInt64() == -1) { IsWatching = false; return; }
905-
906-
do
907-
{
908-
notifyInfo = ref Unsafe.As<byte, FILE_NOTIFY_INFORMATION>(ref buff[offset]);
909-
string FileName = null;
910-
unsafe
911-
{
912-
fixed (char* name = notifyInfo.FileName)
913-
{
914-
FileName = Path.Combine(path, new string(name, 0, (int)notifyInfo.FileNameLength / 2));
915-
}
916-
}
917-
918-
uint action = notifyInfo.Action;
919-
920-
switch (action)
921-
{
922-
case FILE_ACTION_ADDED:
923-
AddFileOrFolder(FileName);
924-
Debug.WriteLine("File " + FileName + " added to working directory.");
925-
break;
926-
case FILE_ACTION_REMOVED:
927-
RemoveFileOrFolder(FilesAndFolders.ToList().First(x => x.ItemPath.Equals(FileName)));
928-
Debug.WriteLine("File " + FileName + " removed from working directory.");
929-
break;
930-
case FILE_ACTION_MODIFIED:
931-
Debug.WriteLine("File " + FileName + " had attributes modified in the working directory.");
932-
break;
933-
case FILE_ACTION_RENAMED_OLD_NAME:
934-
RemoveFileOrFolder(FilesAndFolders.ToList().First(x => x.ItemPath.Equals(FileName)));
935-
Debug.WriteLine("File " + FileName + " will be renamed in the working directory.");
936-
break;
937-
case FILE_ACTION_RENAMED_NEW_NAME:
938-
AddFileOrFolder(FileName);
939-
Debug.WriteLine("File " + FileName + " was renamed in the working directory.");
940-
break;
941-
default:
942-
Debug.WriteLine("File " + FileName + " performed an action in the working directory.");
943-
break;
944-
}
945-
946-
offset += notifyInfo.NextEntryOffset;
947-
948-
} while (notifyInfo.NextEntryOffset != 0 && hWatchDir.ToInt64() != -1);
889+
}
890+
else
891+
{
892+
return;
893+
}
894+
895+
if (x.Status == AsyncStatus.Canceled) { return; }
896+
var rc = WaitForSingleObjectEx(overlapped.hEvent, INFINITE, true);
897+
898+
const uint FILE_ACTION_ADDED = 0x00000001;
899+
const uint FILE_ACTION_REMOVED = 0x00000002;
900+
const uint FILE_ACTION_MODIFIED = 0x00000003;
901+
const uint FILE_ACTION_RENAMED_OLD_NAME = 0x00000004;
902+
const uint FILE_ACTION_RENAMED_NEW_NAME = 0x00000005;
903+
904+
uint offset = 0;
905+
ref var notifyInfo = ref Unsafe.As<byte, FILE_NOTIFY_INFORMATION>(ref buff[offset]);
906+
if (x.Status == AsyncStatus.Canceled) { return; }
907+
908+
do
909+
{
910+
notifyInfo = ref Unsafe.As<byte, FILE_NOTIFY_INFORMATION>(ref buff[offset]);
911+
string FileName = null;
912+
unsafe
913+
{
914+
fixed (char* name = notifyInfo.FileName)
915+
{
916+
FileName = Path.Combine(path, new string(name, 0, (int)notifyInfo.FileNameLength / 2));
917+
}
918+
}
919+
920+
uint action = notifyInfo.Action;
921+
922+
switch (action)
923+
{
924+
case FILE_ACTION_ADDED:
925+
AddFileOrFolder(FileName);
926+
Debug.WriteLine("File " + FileName + " added to working directory.");
927+
break;
928+
case FILE_ACTION_REMOVED:
929+
RemoveFileOrFolder(FilesAndFolders.ToList().First(x => x.ItemPath.Equals(FileName)));
930+
Debug.WriteLine("File " + FileName + " removed from working directory.");
931+
break;
932+
case FILE_ACTION_MODIFIED:
933+
Debug.WriteLine("File " + FileName + " had attributes modified in the working directory.");
934+
break;
935+
case FILE_ACTION_RENAMED_OLD_NAME:
936+
RemoveFileOrFolder(FilesAndFolders.ToList().First(x => x.ItemPath.Equals(FileName)));
937+
Debug.WriteLine("File " + FileName + " will be renamed in the working directory.");
938+
break;
939+
case FILE_ACTION_RENAMED_NEW_NAME:
940+
AddFileOrFolder(FileName);
941+
Debug.WriteLine("File " + FileName + " was renamed in the working directory.");
942+
break;
943+
default:
944+
Debug.WriteLine("File " + FileName + " performed an action in the working directory.");
945+
break;
946+
}
947+
948+
offset += notifyInfo.NextEntryOffset;
949+
950+
} while (notifyInfo.NextEntryOffset != 0 && x.Status != AsyncStatus.Canceled);
949951

950952
//ResetEvent(overlapped.hEvent);
951953
Debug.WriteLine("\n\nTask running...\n\n");
952-
}
953-
}
954-
}
955-
});
954+
}
955+
}
956+
}
957+
});
956958

957959
Debug.WriteLine("\n\nTask exiting...\n\n");
958-
959-
IsWatching = false;
960-
961960
}
962961

963962
public void AddFileOrFolder(ListedItem item)

0 commit comments

Comments
 (0)