예제 #1
0
        /// <summary>
        /// Internally creates and starts the monitor thread.
        /// </summary>
        /// <returns>
        /// True if the thread was successfully created.
        /// To ensure the monitor was successfully activated, handle the MonitorOpened event.
        /// </returns>
        /// <remarks></remarks>
        protected bool internalWatch()
        {
            int blen    = 0;
            int bufflen = (int)_Buff.Size;
            var tbuff   = _Buff.Handle;

            if (_thread is object)
            {
                return(false);
            }
            if (!internalOpenFile())
            {
                return(false);
            }
            FILE_NOTIFY_INFORMATION fn;

            fn.ptr  = _Buff;
            _thread = new System.Threading.Thread(() =>
            {
                var notice = IntPtr.Zero;
                User32.PostMessage(Handle, FileSystemMonitor.WM_SIGNAL_OPEN, IntPtr.Zero, IntPtr.Zero);
                do
                {
                    try
                    {
                        // let's clean up the memory before the next execute.
                        if (blen > 0)
                        {
                            _Buff.ZeroMemory(0L, blen);
                            blen = 0;
                        }

                        if (!FileSystemMonitor.ReadDirectoryChangesW(_hFile, tbuff, bufflen, true, _Filter, ref blen, IntPtr.Zero, IntPtr.Zero))
                        {
                            notice = (IntPtr)User32.GetLastError();
                            break;
                        }
                    }
                    catch (System.Threading.ThreadAbortException)
                    {
                        break;
                    }
                    catch (Exception)
                    {
                        notice = (IntPtr)1;
                        break;
                    }

                    // block until the lock is acquired.  Hopefully the
                    // UI thread will not take that long to clean the list.
                    System.Threading.Monitor.Enter(_WaitList);
                    _WaitList.Add(FSMonitorEventArgs.FromPtr(fn, this));
                    // and we're done ...
                    System.Threading.Monitor.Exit(_WaitList);

                    // post to the UI thread that there are items to dequeue and continue!
                    User32.PostMessage(Handle, FileSystemMonitor.WM_SIGNAL, IntPtr.Zero, IntPtr.Zero);
                }while (true);
                _thread = null;
                User32.PostMessage(Handle, FileSystemMonitor.WM_SIGNAL_CLOSE, IntPtr.Zero, IntPtr.Zero);
            });

            _thread.SetApartmentState(System.Threading.ApartmentState.STA);
            _thread.IsBackground = true;

            _thread.Start();

            return(true);
        }