我实现如下:
[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。 此处也是说不通的。
[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。 此处也是说不通的。
[DllImport("kernel32.dll", SetLastError=true)]
public extern static Int32 WaitForMultipleObjects(...);if( WaitForMultipleObjects(...) == -1)
{
int errCode = Marshal.GetLastWin32Error(); //<---
MessageBox.Show("..." + errCode);
}其实在C#里面可以用:
WaitHandle.WaitAll(...);
不过已经好用了
问题出在
我没把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]);
不过具体的原因还是不知道。