我实现如下:
          [DllImport("kernel32.dll")]
         public extern static Int32 WaitForSingleObject(IntPtr hHandle, Int32 dwMilliseconds); 
         [DllImport("kernel32.dll")]
         public extern static Int32 WaitForMultipleObjects(Int32 nCount, IntPtr [] hHandle, bool fWaitAll, Int32 dwMilliseconds);

   ...    
IntPtr[] hDir = new IntPtr[2];
...
            while (true)
            {
                Int32 wch = WaitForMultipleObjects(2, hDir, false, -1);
                //Int32 wch = WaitForSingleObject(hDir[0], -1);

                switch (wch)
                {
                    case 0:
                        if (FindNextChangeNotification(hDir[0]) == false)
                            return;
                       
                         OndirChanged(System.EventArgs.Empty);
                            break;
                    case 1:
                        return;
                    default:
                        break;
                }
但是多等待返回-1
单等待就好用。个人感觉还是那个句柄指针有问题论坛搜了一个帖子有人回复如下:
[DllImport("kernel32.dll")]   
  static   extern   uint   WaitForMultipleObjects(uint   nCount,   IntPtr   []   lpHandles,   
        bool   bWaitAll,   uint   dwMilliseconds);   
但是这个也是有点问题的
用 uint 如果返回错误呢?? 而且无限等待时的值是-1。 此处也是说不通的。

解决方案 »

  1.   

    -1是出错了,你调用GetLastError来看看出的什么错:
    [DllImport("kernel32.dll", SetLastError=true)]
    public extern static Int32 WaitForMultipleObjects(...);if( WaitForMultipleObjects(...) == -1)
    {
       int errCode = Marshal.GetLastWin32Error();          //<---
       MessageBox.Show("..." + errCode);
    }其实在C#里面可以用:
    WaitHandle.WaitAll(...);
      

  2.   

    回头看看
    不过已经好用了
    问题出在
    我没把hDir【】初始化        public void lisWatcher()
            {
               
     
                hDir[0] = FindFirstChangeNotification(lPath, false, 1);
                 hDir[1] = CreateEvent(IntPtr.Zero, false, false, null);

                while (true)
                {
                    Int32 wch = WaitForMultipleObjects(2, hDir, false, -1);
                    //Int32 wch = WaitForSingleObject(hDir[0], -1);
                    switch (wch)
                    {
                        case 0:
                            if (FindNextChangeNotification(hDir[0]) == false)
                                return;
                           
                             OndirChanged(System.EventArgs.Empty);
                                break;
                        case 1:
                            return;
                        default:
                            break;
                    }
                }
            }
          
    开始时候我只用了
    hDir[0] = FindFirstChangeNotification(lPath, false, 1);
    这个。
     hDir[1] = CreateEvent(IntPtr.Zero, false, false, null);
    在其他地方定义的
    为了设置事件通知线程结束。
    lisWatcher()是个线程函数。
    改成现在这样就好了。在其他地方SetEvent(hDir[1]);
    不过具体的原因还是不知道。