private void InternalThreadProc(object state) { ThreadCount++; int source; string eventName = Guid.NewGuid().ToString(); EventWaitHandle waitHandle = new EventWaitHandle(false, EventResetMode.AutoReset, eventName); if (TestCondition == 0) { Thread.Sleep(1000); } try { while (m_enabled) { if (TestCondition == 1) { Thread.Sleep(1000); } if (m_disposing) { return; } if (TestCondition == 2) { Thread.Sleep(1000); } if (m_useFirstTime) { Notify.RunAppAtTime(string.Format(@"\\.\Notifications\NamedEvents\{0}", eventName), m_firstTime); m_useFirstTime = false; } else { // set up the next event Notify.RunAppAtTime(string.Format(@"\\.\Notifications\NamedEvents\{0}", eventName), DateTime.Now.Add(m_interval)); m_firstTime = DateTime.MinValue; } if (TestCondition == 3) { Thread.Sleep(1000); } if (m_disposing) { return; } source = OpenNETCF.Threading.EventWaitHandle.WaitAny(new WaitHandle[] { waitHandle, m_quitHandle }); if (TestCondition == 4) { Thread.Sleep(1000); } // see if it's the event if (source == 0) { m_cachedEnabled = null; // fire the event if we have a listener if (Tick != null) { // we need to decouple this call from the current thread or the lock will do nothing ThreadPool.QueueUserWorkItem(new WaitCallback( delegate { Tick(this, null); })); } if (TestCondition == 5) { Thread.Sleep(1000); } if (OneShot) { if (TestCondition == 6) { Thread.Sleep(1000); } if (m_cachedEnabled != null) { if (TestCondition == 7) { Thread.Sleep(1000); } m_enabled = (m_cachedEnabled == true); if (TestCondition == 8) { Thread.Sleep(1000); } } else { m_enabled = false; } } } else { m_enabled = false; } } } finally { waitHandle.Close(); ThreadCount--; if (ThreadCount == 0) { m_quitHandle.Reset(); } } }
private unsafe void ThreadProc() { IntPtr notifyHandle = NativeMethods.FindFirstChangeNotification(m_path, true, filter); FileNotifyInformation notifyData = new FileNotifyInformation(); uint returned = 0; uint available = 0; EventWaitHandle ewh = new EventWaitHandle(false, EventResetMode.ManualReset, WaitHandleName); EventWaitHandle quitWaitHandle = new EventWaitHandle(false, EventResetMode.ManualReset, WaitHandleNameQuit); while (!m_quit) { ewh.Reset(); if (EventWaitHandle.WaitAny(new IntPtr[] { notifyHandle, ewh.Handle }, TimeoutInfinite, false) != EventWaitHandle.WaitTimeout) { if (m_quit) { break; } IntPtr ptr = IntPtr.Zero; if (NativeMethods.CeGetFileNotificationInfo(notifyHandle, 0, ref ptr, 0, ref returned, ref available)) { if (available > 0) { int maxData = 2048; fixed(byte *pData = new byte[maxData]) { // get data if (NativeMethods.CeGetFileNotificationInfo(notifyHandle, 0, pData, maxData, ref returned, ref available)) { notifyData = new FileNotifyInformation(pData, 0); // handle data in notifyData if (ValidateByFilter(notifyData.Filename)) { RaiseEvents(notifyData.Action, notifyData.Filename); } int offset = 0; offset += notifyData.NextEntryOffset; while (notifyData.NextEntryOffset > 0) { notifyData = new FileNotifyInformation(pData, offset); if (ValidateByFilter(notifyData.Filename)) { RaiseEvents(notifyData.Action, notifyData.Filename); } offset += notifyData.NextEntryOffset; } } } } else { //Seems that subdirectories don't return anything but then the notifyHandle is never reset and if available data is 0 notifyHandle never resets NativeMethods.FindCloseChangeNotification(notifyHandle); notifyHandle = NativeMethods.FindFirstChangeNotification(m_path, true, filter); } } } // if( waithandle... } // while (!m_quit) NativeMethods.FindCloseChangeNotification(notifyHandle); quitWaitHandle.Set(); }