Проблема с состоянием делегата. PreAllocatedOverlapped при изменении папки мониторинга. ⇐ C#
-
Anonymous
Проблема с состоянием делегата. PreAllocatedOverlapped при изменении папки мониторинга.
We've encountered an issue while developing an application called 'DC Watcher' to monitor local file system changes and notify us with event . Unfortunately, it's not functioning as expected for user profile folders.
Problem: We identified that the delegate state.PreAllocatedOverlapped (ref in below code) is not being called when there are changes in the local workspace. This appears to be a Windows callback issue. The application works perfectly fine for non-user folders. Note: • We are using a VDI environment, roaming profile and users do not have admin privileges. • It doesn't seem to be a permission issue, as we can write to the user folder.
Code Snippet: Below is the relevant code snippet where we've placed logs.
private void StartRaisingEvents() { Console.WriteLine("inside StartRaisingEvents"); // If we're already running, don't do anything. if (!IsHandleInvalid(_directoryHandle)) { Console.WriteLine("level1 - IsHandleInvalid false"); return; } // Create handle to directory being monitored _directoryHandle = CreateFile( lpFileName: _directory, dwDesiredAccess: FileListDirectory, dwShareMode: (uint)(FileShare.Read | FileShare.Delete | FileShare.Write), lpSecurityAttributes: IntPtr.Zero, dwCreationDisposition: (uint)(FileMode.Open), dwFlagsAndAttributes: BackupSemanticsAndOverlapped, hTemplateFile: IntPtr.Zero); if (IsHandleInvalid(_directoryHandle)) { Console.WriteLine("Level2 - IsHandleInvalid true"); _directoryHandle = null; throw new FileNotFoundException(_directory); } // Create the state associated with the operation of monitoring the direction AsyncReadState state; try { Console.WriteLine("StartRaisingEvents 1"); // Start ignoring all events that were initiated before this, and // allocate the buffer to be pinned and used for the duration of the operation int session = Interlocked.Increment(ref _currentSession); byte[] buffer = AllocateBuffer(); // Store all state, including a preallocated overlapped, into the state object that'll be // passed from iteration to iteration during the lifetime of the operation. The buffer will be pinned // from now until the end of the operation. state = new AsyncReadState(session, buffer, _directoryHandle, ThreadPoolBoundHandle.BindHandle(_directoryHandle), this); Console.WriteLine("StartRaisingEvents 2"); unsafe { Console.WriteLine("StartRaisingEvents 3"); state.PreAllocatedOverlapped = new PreAllocatedOverlapped((errorCode, numBytes, overlappedPointer) => { Console.WriteLine("StartRaisingEvents 4"); AsyncReadState state = (AsyncReadState)ThreadPoolBoundHandle.GetNativeOverlappedState(overlappedPointer); state.ThreadPoolBinding.FreeNativeOverlapped(overlappedPointer); if (state.WeakWatcher.TryGetTarget(out FileSystemWatcherEx? watcher)) { watcher.ReadDirectoryChangesCallback(errorCode, numBytes, state); } Console.WriteLine("StartRaisingEvents 5"); }, state, buffer); if (state.PreAllocatedOverlapped == null) { Console.WriteLine("(state.PreAllocatedOverlapped == null"); } else { Console.WriteLine("(state.PreAllocatedOverlapped != null"); } Console.WriteLine("StartRaisingEvents 6"); } Console.WriteLine("StartRaisingEvents 7"); } catch (Exception ex) { Console.WriteLine("StartRaisingEvents: " + ex.Message); // Make sure we don't leave a valid directory handle set if we're not running _directoryHandle.Dispose(); _directoryHandle = null; throw; } // Start monitoring _enabled = true; Monitor(state); } We observed differences in the output when monitoring user folders (for C:\Users\ritesh.gadodia\DC) and non-user folders (C:\Autodesk).
Output Differences: When monitoring the user folder, we observed the following log output, After Startup log nothing is recorded in the log when we are adding files:
Watcher is created for path C:\Users\ritesh.gadodia\DC inside StartRaisingEvents StartRaisingEvents 1 StartRaisingEvents 2 Monitor finally Watcher Started! When monitoring the non-user folder. After Startup log, We can see event are raised and everyhting is working properly:
Watcher is created for path C:\Autodesk inside StartRaisingEvents StartRaisingEvents 1 StartRaisingEvents 2 Monitor finally Watcher Started! StartRaisingEvents 3 StartRaisingEvents 4 **Watcher_Created** C:\Autodesk\New Text Document.txt StartRaisingEvents 3 StartRaisingEvents 4 **Watcher_Renamed C:\Autodesk\Ganesh.txt** Monitor finally Request for Assistance: If anyone has insights, suggestions, or experiences with a similar scenario, we would greatly appreciate your assistance.
Источник: https://stackoverflow.com/questions/780 ... er-changes
We've encountered an issue while developing an application called 'DC Watcher' to monitor local file system changes and notify us with event . Unfortunately, it's not functioning as expected for user profile folders.
Problem: We identified that the delegate state.PreAllocatedOverlapped (ref in below code) is not being called when there are changes in the local workspace. This appears to be a Windows callback issue. The application works perfectly fine for non-user folders. Note: • We are using a VDI environment, roaming profile and users do not have admin privileges. • It doesn't seem to be a permission issue, as we can write to the user folder.
Code Snippet: Below is the relevant code snippet where we've placed logs.
private void StartRaisingEvents() { Console.WriteLine("inside StartRaisingEvents"); // If we're already running, don't do anything. if (!IsHandleInvalid(_directoryHandle)) { Console.WriteLine("level1 - IsHandleInvalid false"); return; } // Create handle to directory being monitored _directoryHandle = CreateFile( lpFileName: _directory, dwDesiredAccess: FileListDirectory, dwShareMode: (uint)(FileShare.Read | FileShare.Delete | FileShare.Write), lpSecurityAttributes: IntPtr.Zero, dwCreationDisposition: (uint)(FileMode.Open), dwFlagsAndAttributes: BackupSemanticsAndOverlapped, hTemplateFile: IntPtr.Zero); if (IsHandleInvalid(_directoryHandle)) { Console.WriteLine("Level2 - IsHandleInvalid true"); _directoryHandle = null; throw new FileNotFoundException(_directory); } // Create the state associated with the operation of monitoring the direction AsyncReadState state; try { Console.WriteLine("StartRaisingEvents 1"); // Start ignoring all events that were initiated before this, and // allocate the buffer to be pinned and used for the duration of the operation int session = Interlocked.Increment(ref _currentSession); byte[] buffer = AllocateBuffer(); // Store all state, including a preallocated overlapped, into the state object that'll be // passed from iteration to iteration during the lifetime of the operation. The buffer will be pinned // from now until the end of the operation. state = new AsyncReadState(session, buffer, _directoryHandle, ThreadPoolBoundHandle.BindHandle(_directoryHandle), this); Console.WriteLine("StartRaisingEvents 2"); unsafe { Console.WriteLine("StartRaisingEvents 3"); state.PreAllocatedOverlapped = new PreAllocatedOverlapped((errorCode, numBytes, overlappedPointer) => { Console.WriteLine("StartRaisingEvents 4"); AsyncReadState state = (AsyncReadState)ThreadPoolBoundHandle.GetNativeOverlappedState(overlappedPointer); state.ThreadPoolBinding.FreeNativeOverlapped(overlappedPointer); if (state.WeakWatcher.TryGetTarget(out FileSystemWatcherEx? watcher)) { watcher.ReadDirectoryChangesCallback(errorCode, numBytes, state); } Console.WriteLine("StartRaisingEvents 5"); }, state, buffer); if (state.PreAllocatedOverlapped == null) { Console.WriteLine("(state.PreAllocatedOverlapped == null"); } else { Console.WriteLine("(state.PreAllocatedOverlapped != null"); } Console.WriteLine("StartRaisingEvents 6"); } Console.WriteLine("StartRaisingEvents 7"); } catch (Exception ex) { Console.WriteLine("StartRaisingEvents: " + ex.Message); // Make sure we don't leave a valid directory handle set if we're not running _directoryHandle.Dispose(); _directoryHandle = null; throw; } // Start monitoring _enabled = true; Monitor(state); } We observed differences in the output when monitoring user folders (for C:\Users\ritesh.gadodia\DC) and non-user folders (C:\Autodesk).
Output Differences: When monitoring the user folder, we observed the following log output, After Startup log nothing is recorded in the log when we are adding files:
Watcher is created for path C:\Users\ritesh.gadodia\DC inside StartRaisingEvents StartRaisingEvents 1 StartRaisingEvents 2 Monitor finally Watcher Started! When monitoring the non-user folder. After Startup log, We can see event are raised and everyhting is working properly:
Watcher is created for path C:\Autodesk inside StartRaisingEvents StartRaisingEvents 1 StartRaisingEvents 2 Monitor finally Watcher Started! StartRaisingEvents 3 StartRaisingEvents 4 **Watcher_Created** C:\Autodesk\New Text Document.txt StartRaisingEvents 3 StartRaisingEvents 4 **Watcher_Renamed C:\Autodesk\Ganesh.txt** Monitor finally Request for Assistance: If anyone has insights, suggestions, or experiences with a similar scenario, we would greatly appreciate your assistance.
Источник: https://stackoverflow.com/questions/780 ... er-changes
Мобильная версия