I m试图为我的<代码>FileWatcher类别撰写一个单位测试。
- The handle returned from
FindFirstChangeNotification
- A handle for an Event that lets me cancel the above wait.
因此,基本上,
现在,在试图写造法时,我需要等待它开始等待。
《白奴法典》:
FileWatcher.Wait(INFINITE)
ChangeFile()
// Verify that FileWatcher works (with some other event - unimportant...)
问题是,存在着种族条件。 首先,我需要确保FilWatcher开始等待(即现在其胎面在<代码>上被阻断)。 WaitForMultipleObjects之前,我可以启动第2行的档案改动。 我不想使用。 睡觉,因为睡觉似乎很 ha,在偷渡时,必然给我带来问题。
我很熟悉<代码>SignalObjectAndWait,但它确实没有解决我的问题,因为我需要“SignalObjectAndWaitOnMultipleObjects”。
任何想法?
<><>Edit>/strong>
为澄清一个范围,此处为<代码>的简化版本。 文件:
// 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;
};
它继承了<条码>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, FALSE, INFINITE);
if (hWaitDone == WAIT_OBJECT_0)
OnChange();
else
return Thread::THREAD_ABORTED;
}
return THREAD_FINISHED;
通知说,校对功能等待两种操作,一种是变更通知,另一种是“站式”活动(从校对传)。
现在,测试这一类的法典就是这样:
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();
}
};
CNPUnit测试援引:
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);
想法是在中间摆脱这种睡觉。