示例#1
0
        private async Task SetDirectoryHandle()
        {
            await Task.Run(() =>
            {
                var directoryHandle = WindowsFacade.CreateFile(
                    Config.PathToWatch,
                    FileSystemConstants.FileListDirectory, // access (read-write) mode
                    FileSystemConstants.FileShareRead | FileSystemConstants.FileShareDelete |
                    FileSystemConstants.FileShareWrite,    // share mode
                    null,                                  // security descriptor
                    FileSystemConstants.OpenExisting,      // how to create
                    FileSystemConstants.FileFlagBackupSemantics | FileSystemConstants.FileFlagOverlapped,
                    // file attributes
                    new SafeFileHandle(IntPtr.Zero, false)     // file with attributes to copy
                    );

                if (!directoryHandle.IsHandleValid())
                {
                    throw new ApplicationException(
                        $"Swatcher failed to start because it couldn't access the folder path provided in configuration.");
                }

                DirectoryHandle = directoryHandle;
            })
            .ConfigureAwait(false);
        }
示例#2
0
        private unsafe void SignalWorkerThreadsToStop()
        {
            Observable.Interval(TimeSpan.FromMilliseconds(25))
            .TakeWhile(_ => _runningThreads > 0)
            .Select(_ =>
            {
                var result = new SwatcherAsyncResult {
                    Buffer = new byte[0]
                };
                var overlapped = new Overlapped {
                    AsyncResult = result
                };

                //the first parameter is null because we're not using IO completion callbacks; they're too slow.
                //we're taking the byte array from our empty byte array and passing that as user data to the overlapped.
                var overlappedPointer = overlapped.UnsafePack(null, result.Buffer);
                //when using IOCPs, we can send our own custom messages to the GetQueuedCompletionStatus
                //method by call PostQueuedCompletionStatus. In this case, we want to stop the threads that are
                //waiting on change events, so we will send a custom completion key "StopIocpThreads".
                WindowsFacade.PostQueuedCompletionStatus(CompletionPortHandle, 0, StopIocpThreads, overlappedPointer);
                return(Unit.Default);
            })
            .AsCompletion()
            .Where(_ => Config.LoggingEnabled)
            .Subscribe(_ =>
            {
                Disposables.Dispose();
                Logger.Info("Swatcher has stopped");
            });
        }
示例#3
0
        private async Task SetCompletionPortHandle(int completionKey)
        {
            await Task.Run(() =>
            {
                //if the completion port doesn't exist yet, this call will create it.
                //if it already exists, this call will bind the directory handle to the completion port,
                //whilst retaining any other directory handles that were previously bound.
                //passing 0 to the last parameter uses the default number of concurrent threads, which
                //is the number of CPUs on the machine.
                var pointer = WindowsFacade.CreateIoCompletionPort(
                    DirectoryHandle, SafeLocalMemHandle.Empty,
                    (uint)completionKey, (uint)Environment.ProcessorCount);

                CompletionPortHandle = new SafeLocalMemHandle(pointer);
            })
            .ConfigureAwait(false);
        }