@@ -51,8 +51,7 @@ public class ItemViewModel : ObservableObject, IDisposable
51
51
private readonly ConcurrentQueue < ( uint Action , string FileName ) > operationQueue ;
52
52
private readonly ConcurrentDictionary < string , bool > itemLoadQueue ;
53
53
private readonly AsyncManualResetEvent operationEvent ;
54
- private IntPtr hWatchDir ;
55
- private IAsyncAction aWatcherAction ;
54
+ private IAsyncAction aProcessQueueAction ;
56
55
57
56
// files and folders list for manipulating
58
57
private List < ListedItem > filesAndFolders ;
@@ -68,7 +67,7 @@ public class ItemViewModel : ObservableObject, IDisposable
68
67
private bool shouldDisplayFileExtensions = false ;
69
68
public ListedItem CurrentFolder { get ; private set ; }
70
69
public CollectionViewSource viewSource ;
71
- private CancellationTokenSource addFilesCTS , semaphoreCTS , loadPropsCTS ;
70
+ private CancellationTokenSource addFilesCTS , semaphoreCTS , loadPropsCTS , watcherCTS ;
72
71
73
72
public event EventHandler DirectoryInfoUpdated ;
74
73
@@ -359,6 +358,7 @@ public ItemViewModel(FolderSettingsViewModel folderSettingsViewModel)
359
358
addFilesCTS = new CancellationTokenSource ( ) ;
360
359
semaphoreCTS = new CancellationTokenSource ( ) ;
361
360
loadPropsCTS = new CancellationTokenSource ( ) ;
361
+ watcherCTS = new CancellationTokenSource ( ) ;
362
362
operationEvent = new AsyncManualResetEvent ( ) ;
363
363
enumFolderSemaphore = new SemaphoreSlim ( 1 , 1 ) ;
364
364
shouldDisplayFileExtensions = UserSettingsService . PreferencesSettingsService . ShowFileExtensions ;
@@ -1338,25 +1338,14 @@ private void AssignDefaultIcons()
1338
1338
1339
1339
public void CloseWatcher ( )
1340
1340
{
1341
- if ( aWatcherAction != null )
1341
+ if ( aProcessQueueAction != null )
1342
1342
{
1343
- aWatcherAction ? . Cancel ( ) ;
1344
-
1345
- if ( aWatcherAction . Status != AsyncStatus . Started )
1346
- {
1347
- aWatcherAction = null ; // Prevent duplicate execution of this block
1348
- Debug . WriteLine ( "watcher canceled" ) ;
1349
- CancelIoEx ( hWatchDir , IntPtr . Zero ) ;
1350
- Debug . WriteLine ( "watcher handle closed" ) ;
1351
- CloseHandle ( hWatchDir ) ;
1352
- }
1353
- }
1354
- if ( watchedItemsOperation != null )
1355
- {
1356
- itemQueryResult . ContentsChanged -= ItemQueryResult_ContentsChanged ;
1357
- watchedItemsOperation ? . Cancel ( ) ;
1358
- watchedItemsOperation = null ;
1343
+ aProcessQueueAction ? . Cancel ( ) ;
1344
+ aProcessQueueAction = null ; // Prevent duplicate execution of this block
1345
+ Debug . WriteLine ( "process queue canceled" ) ;
1359
1346
}
1347
+ watcherCTS ? . Cancel ( ) ;
1348
+ watcherCTS = new CancellationTokenSource ( ) ;
1360
1349
}
1361
1350
1362
1351
public async Task EnumerateItemsFromSpecialFolderAsync ( string path )
@@ -1743,8 +1732,6 @@ private async Task<CloudDriveSyncStatus> CheckCloudDriveSyncStatusAsync(IStorage
1743
1732
1744
1733
private StorageItemQueryResult itemQueryResult ;
1745
1734
1746
- private IAsyncOperation < IReadOnlyList < IStorageItem > > watchedItemsOperation ;
1747
-
1748
1735
private async void WatchForStorageFolderChanges ( BaseStorageFolder rootFolder )
1749
1736
{
1750
1737
if ( rootFolder == null )
@@ -1764,7 +1751,12 @@ await Task.Run(() =>
1764
1751
{
1765
1752
itemQueryResult = rootFolder . CreateItemQueryWithOptions ( options ) . ToStorageItemQueryResult ( ) ;
1766
1753
itemQueryResult . ContentsChanged += ItemQueryResult_ContentsChanged ;
1767
- watchedItemsOperation = itemQueryResult . GetItemsAsync ( 0 , 1 ) ; // Just get one item to start getting notifications
1754
+ var watchedItemsOperation = itemQueryResult . GetItemsAsync ( 0 , 1 ) ; // Just get one item to start getting notifications
1755
+ watcherCTS . Token . Register ( ( ) =>
1756
+ {
1757
+ itemQueryResult . ContentsChanged -= ItemQueryResult_ContentsChanged ;
1758
+ watchedItemsOperation ? . Cancel ( ) ;
1759
+ } ) ;
1768
1760
}
1769
1761
} ) ;
1770
1762
}
@@ -1790,8 +1782,8 @@ await CoreApplication.MainView.DispatcherQueue.EnqueueAsync(() =>
1790
1782
1791
1783
private void WatchForDirectoryChanges ( string path , CloudDriveSyncStatus syncStatus )
1792
1784
{
1793
- Debug . WriteLine ( "WatchForDirectoryChanges: {0}" , path ) ;
1794
- hWatchDir = NativeFileOperationsHelper . CreateFileFromApp ( path , 1 , 1 | 2 | 4 ,
1785
+ Debug . WriteLine ( $ "WatchForDirectoryChanges: { path } " ) ;
1786
+ var hWatchDir = NativeFileOperationsHelper . CreateFileFromApp ( path , 1 , 1 | 2 | 4 ,
1795
1787
IntPtr . Zero , 3 , ( uint ) NativeFileOperationsHelper . File_Attributes . BackupSemantics | ( uint ) NativeFileOperationsHelper . File_Attributes . Overlapped , IntPtr . Zero ) ;
1796
1788
if ( hWatchDir . ToInt64 ( ) == - 1 )
1797
1789
{
@@ -1800,10 +1792,12 @@ private void WatchForDirectoryChanges(string path, CloudDriveSyncStatus syncStat
1800
1792
1801
1793
var hasSyncStatus = syncStatus != CloudDriveSyncStatus . NotSynced && syncStatus != CloudDriveSyncStatus . Unknown ;
1802
1794
1803
- var cts = new CancellationTokenSource ( ) ;
1804
- _ = Windows . System . Threading . ThreadPool . RunAsync ( ( x ) => ProcessOperationQueue ( cts . Token , hasSyncStatus ) ) ;
1795
+ if ( aProcessQueueAction == null ) // Only start one ProcessOperationQueue
1796
+ {
1797
+ aProcessQueueAction = Windows . System . Threading . ThreadPool . RunAsync ( ( x ) => ProcessOperationQueue ( x , hasSyncStatus ) ) ;
1798
+ }
1805
1799
1806
- aWatcherAction = Windows . System . Threading . ThreadPool . RunAsync ( ( x ) =>
1800
+ var aWatcherAction = Windows . System . Threading . ThreadPool . RunAsync ( ( x ) =>
1807
1801
{
1808
1802
byte [ ] buff = new byte [ 4096 ] ;
1809
1803
var rand = Guid . NewGuid ( ) ;
@@ -1883,14 +1877,23 @@ private void WatchForDirectoryChanges(string path, CloudDriveSyncStatus syncStat
1883
1877
}
1884
1878
CloseHandle ( overlapped . hEvent ) ;
1885
1879
operationQueue . Clear ( ) ;
1886
- cts . Cancel ( ) ;
1887
1880
Debug . WriteLine ( "aWatcherAction done: {0}" , rand ) ;
1888
1881
} ) ;
1889
1882
1890
- Debug . WriteLine ( "Task exiting..." ) ;
1883
+ watcherCTS . Token . Register ( ( ) =>
1884
+ {
1885
+ if ( aWatcherAction != null )
1886
+ {
1887
+ aWatcherAction ? . Cancel ( ) ;
1888
+ aWatcherAction = null ; // Prevent duplicate execution of this block
1889
+ Debug . WriteLine ( "watcher canceled" ) ;
1890
+ }
1891
+ CancelIoEx ( hWatchDir , IntPtr . Zero ) ;
1892
+ CloseHandle ( hWatchDir ) ;
1893
+ } ) ;
1891
1894
}
1892
1895
1893
- private async void ProcessOperationQueue ( CancellationToken cancellationToken , bool hasSyncStatus )
1896
+ private async void ProcessOperationQueue ( IAsyncAction action , bool hasSyncStatus )
1894
1897
{
1895
1898
ApplicationDataContainer localSettings = ApplicationData . Current . LocalSettings ;
1896
1899
string returnformat = Enum . Parse < TimeStyle > ( localSettings . Values [ Constants . LocalSettings . DateTimeFormat ] . ToString ( ) ) == TimeStyle . Application ? "D" : "g" ;
@@ -1910,15 +1913,15 @@ private async void ProcessOperationQueue(CancellationToken cancellationToken, bo
1910
1913
1911
1914
try
1912
1915
{
1913
- while ( ! cancellationToken . IsCancellationRequested )
1916
+ while ( action . Status != AsyncStatus . Canceled )
1914
1917
{
1915
- if ( await operationEvent . WaitAsync ( 200 , cancellationToken ) )
1918
+ if ( await operationEvent . WaitAsync ( 200 ) )
1916
1919
{
1917
1920
operationEvent . Reset ( ) ;
1918
1921
1919
1922
while ( operationQueue . TryDequeue ( out var operation ) )
1920
1923
{
1921
- if ( cancellationToken . IsCancellationRequested ) break ;
1924
+ if ( action . Status == AsyncStatus . Canceled ) break ;
1922
1925
try
1923
1926
{
1924
1927
switch ( operation . Action )
@@ -1927,7 +1930,7 @@ private async void ProcessOperationQueue(CancellationToken cancellationToken, bo
1927
1930
lastItemAdded = await AddFileOrFolderAsync ( operation . FileName , returnformat ) ;
1928
1931
if ( lastItemAdded != null )
1929
1932
{
1930
- anyEdits = true ;
1933
+ anyEdits = true ;
1931
1934
}
1932
1935
break ;
1933
1936
@@ -1992,8 +1995,8 @@ private async void ProcessOperationQueue(CancellationToken cancellationToken, bo
1992
1995
{
1993
1996
await OrderFilesAndFoldersAsync ( ) ;
1994
1997
await ApplyFilesAndFoldersChangesAsync ( ) ;
1995
- if ( lastItemAdded != null )
1996
- {
1998
+ if ( lastItemAdded != null )
1999
+ {
1997
2000
await NotifyListedItemAddedAsync ( lastItemAdded ) ;
1998
2001
}
1999
2002
anyEdits = false ;
0 commit comments