我正在为我的FileWatcher类写一个unit testing。
FileWatcher派生自一个Thread类并使用WaitForMultipleObjects在其线程过程中等待两个句柄:
从FindFirstChangeNotification返回的句柄
一个事件的句柄,让我取消上面的等待。
所以基本上FileWatcher首先等待:文件改变或者我告诉它停止观看。
现在,当试图编写testing这个类的代码时,我需要等待它开始等待。
将vector声明为类成员
find缓冲区地址来创buildshell代码
Environment.GetFolderPath(Environment.SpecialFolder.System)和Environment.SystemDirectory for System32文件夹之间的区别
我在哪里可以获得编程反馈
如何设置QTableWidget高度在70以下
Peusdo代码:
FileWatcher.Wait(INFINITE) ChangeFile() // Verify that FileWatcher works (with some other event - unimportant...)
问题是有一个竞争条件。 我需要首先确保FileWatcher已经开始等待(即它的线程现在被阻塞在WaitForMultipleObjects ),然后才能触发第二行中的文件更改。 我不想使用睡觉,因为,好吧,它似乎很乱,必将给我debugging时的问题。
我熟悉SignalObjectAndWait ,但它并不真正解决我的问题,因为我需要它“SignalObjectAndWaitOnMultipleObjects”…
有任何想法吗?
编辑
为了澄清一下,下面是FileWatcher类的简化版本:
// Inherit from this class,override OnChange,and call Start() to turn on monitoring. class FileChangeWatcher : public Utils::Thread { public: // File must exist before constructing this instance FileChangeWatcher(const std::string& filename); virtual int Run(); virtual void OnChange() = 0; };
它inheritance了Thread并实现了线程函数,看起来像这样(非常简化):
_changeEvent = ::FindFirstChangeNotificationW(wfn.c_str(),FALSE,FILE_NOTIFY_CHANGE_LAST_WRITE); HANDLE events[2] = { _changeEvent,m_hStopEvent }; DWORD hWaitDone = WAIT_OBJECT_0; while (hWaitDone == WAIT_OBJECT_0) { hWaitDone = ::WaitForMultipleObjects(2,events,INFINITE); if (hWaitDone == WAIT_OBJECT_0) OnChange(); else return Thread::THREAD_ABORTED; } return THREAD_FINISHED;
请注意,线程函数等待两个句柄,一个是更改通知,另一个是“停止线程”事件(从线程inheritance)。
现在testing这个类的代码如下所示:
class TestFileWatcher : public FileChangeWatcher { public: bool Changed; Event evtDone; TestFileWatcher(const std::string& fname) : FileChangeWatcher(fname) { Changed = false; } virtual void OnChange() { Changed = true; evtDone.Set(); } };
并从CPPUnittesting中调用:
std::string tempFile = TempFilePath(); StringToFile("Hello,file",tempFile); TestFileWatcher tfw(tempFile); tfw.Start(); ::Sleep(100); // Ugly,but we have to wait for monitor to kick in in worker thread StringToFile("Modify me",tempFile); tfw.evtDone.Wait(INFINITE); CPPUNIT_ASSERT(tfw.Changed);
这个想法是摆脱中间的睡眠。
通过C ++检查以太网上的Windows计算机
将WriteFile()是primefaces,如果进程被终止,但系统继续运行?
memcached – 与C#asp.net应用程序一起使用
C的任务库?
如何从Windows上的c ++控制台应用程序打印UTF-8
没有比赛,您不必等待FileWatcher输入WaitForMultipleObjects 。 如果在调用函数之前执行更改,它将立即返回。
编辑:我现在可以看到比赛。 你为什么不移动下面的行
_changeEvent = ::FindFirstChangeNotificationW(/*...*/);
从线程函数到FileChangeWatcher的构造函数? 这样,您可以确定,在调用StringToFile函数时,文件已被监视。
您应该在观察者的构造函数中调用FindFirstChangeNotification() ,并存储返回的线程函数的句柄。 这意味着您将从施工之初就抓住变化事件。
一旦你的线程已经开始,它只需要调用两个句柄的等待。 如果在线程启动之前发生了更改,则返回的FindFirstChangeNotification()返回的句柄将被发送,并且将会处理更改。 如果希望线程监视许多更改,则应该在处理每个通知后循环并调用FindNextChangeNotification() 。
相反,你可以使用Mutex吗? 在一个线程可以访问它所需要的资源之前,它必须锁定互斥锁并将其解锁为其他需要该资源的线程。
调用CreateEvent()来创建一个非信号事件。 当观察者线程进入其主循环(或其他)时,SetEvent()。 同时,在FileWatcher首先对事件的WaitForSingleObject(),然后一旦返回,WFMO就像你之前做的那样。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 [email protected] 举报,一经查实,本站将立刻删除。