[Common]Use folder_change_reader in file watcher to improve performance (#30827)
This commit is contained in:
Родитель
4ce38d192d
Коммит
4f06f2a659
|
@ -1,5 +1,6 @@
|
|||
#include "pch.h"
|
||||
#include "FileWatcher.h"
|
||||
#include <utils/winapi_error.h>
|
||||
|
||||
std::optional<FILETIME> FileWatcher::MyFileTime()
|
||||
{
|
||||
|
@ -19,50 +20,47 @@ std::optional<FILETIME> FileWatcher::MyFileTime()
|
|||
return result;
|
||||
}
|
||||
|
||||
void FileWatcher::Run()
|
||||
{
|
||||
while (1)
|
||||
{
|
||||
auto lastWrite = MyFileTime();
|
||||
if (!m_lastWrite.has_value())
|
||||
{
|
||||
m_lastWrite = lastWrite;
|
||||
}
|
||||
else if (lastWrite.has_value())
|
||||
{
|
||||
if (m_lastWrite->dwHighDateTime != lastWrite->dwHighDateTime ||
|
||||
m_lastWrite->dwLowDateTime != lastWrite->dwLowDateTime)
|
||||
{
|
||||
m_lastWrite = lastWrite;
|
||||
m_callback();
|
||||
}
|
||||
}
|
||||
|
||||
if (WaitForSingleObject(m_abortEvent, m_refreshPeriod) == WAIT_OBJECT_0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
FileWatcher::FileWatcher(const std::wstring& path, std::function<void()> callback, DWORD refreshPeriod) :
|
||||
m_refreshPeriod(refreshPeriod),
|
||||
FileWatcher::FileWatcher(const std::wstring& path, std::function<void()> callback) :
|
||||
m_path(path),
|
||||
m_callback(callback)
|
||||
{
|
||||
m_abortEvent = CreateEventW(nullptr, TRUE, FALSE, nullptr);
|
||||
if (m_abortEvent)
|
||||
std::filesystem::path fsPath(path);
|
||||
m_file_name = fsPath.filename();
|
||||
std::transform(m_file_name.begin(), m_file_name.end(), m_file_name.begin(), ::towlower);
|
||||
m_folder_change_reader = wil::make_folder_change_reader_nothrow(
|
||||
fsPath.parent_path().c_str(),
|
||||
false,
|
||||
wil::FolderChangeEvents::LastWriteTime,
|
||||
[this](wil::FolderChangeEvent, PCWSTR fileName) {
|
||||
std::wstring lowerFileName(fileName);
|
||||
std::transform(lowerFileName.begin(), lowerFileName.end(), lowerFileName.begin(), ::towlower);
|
||||
|
||||
if (m_file_name.compare(fileName) == 0)
|
||||
{
|
||||
auto lastWrite = MyFileTime();
|
||||
if (!m_lastWrite.has_value())
|
||||
{
|
||||
m_lastWrite = lastWrite;
|
||||
}
|
||||
else if (lastWrite.has_value())
|
||||
{
|
||||
if (m_lastWrite->dwHighDateTime != lastWrite->dwHighDateTime ||
|
||||
m_lastWrite->dwLowDateTime != lastWrite->dwLowDateTime)
|
||||
{
|
||||
m_lastWrite = lastWrite;
|
||||
m_callback();
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
if (!m_folder_change_reader)
|
||||
{
|
||||
m_thread = std::thread([this]() { Run(); });
|
||||
Logger::error(L"Failed to start folder change reader for path {}. {}", path, get_last_error_or_default(GetLastError()));
|
||||
}
|
||||
}
|
||||
|
||||
FileWatcher::~FileWatcher()
|
||||
{
|
||||
if (m_abortEvent)
|
||||
{
|
||||
SetEvent(m_abortEvent);
|
||||
m_thread.join();
|
||||
CloseHandle(m_abortEvent);
|
||||
}
|
||||
m_folder_change_reader.reset();
|
||||
}
|
||||
|
|
|
@ -11,16 +11,14 @@
|
|||
|
||||
class FileWatcher
|
||||
{
|
||||
DWORD m_refreshPeriod;
|
||||
std::wstring m_path;
|
||||
std::wstring m_file_name;
|
||||
std::optional<FILETIME> m_lastWrite;
|
||||
std::function<void()> m_callback;
|
||||
HANDLE m_abortEvent;
|
||||
std::thread m_thread;
|
||||
|
||||
wil::unique_folder_change_reader_nothrow m_folder_change_reader;
|
||||
|
||||
std::optional<FILETIME> MyFileTime();
|
||||
void Run();
|
||||
public:
|
||||
FileWatcher(const std::wstring& path, std::function<void()> callback, DWORD refreshPeriod = 1000);
|
||||
FileWatcher(const std::wstring& path, std::function<void()> callback);
|
||||
~FileWatcher();
|
||||
};
|
||||
|
|
|
@ -47,10 +47,15 @@
|
|||
<ProjectReference Include="..\..\common\version\version.vcxproj">
|
||||
<Project>{cc6e41ac-8174-4e8a-8d22-85dd7f4851df}</Project>
|
||||
</ProjectReference>
|
||||
<ProjectReference Include="..\logger\logger.vcxproj">
|
||||
<Project>{d9b8fc84-322a-4f9f-bbb9-20915c47ddfd}</Project>
|
||||
</ProjectReference>
|
||||
</ItemGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
||||
<Import Project="..\..\..\deps\spdlog.props" />
|
||||
<ImportGroup Label="ExtensionTargets">
|
||||
<Import Project="..\..\..\packages\Microsoft.Windows.CppWinRT.2.0.221104.6\build\native\Microsoft.Windows.CppWinRT.targets" Condition="Exists('..\..\..\packages\Microsoft.Windows.CppWinRT.2.0.221104.6\build\native\Microsoft.Windows.CppWinRT.targets')" />
|
||||
<Import Project="..\..\..\packages\Microsoft.Windows.ImplementationLibrary.1.0.220914.1\build\native\Microsoft.Windows.ImplementationLibrary.targets" Condition="Exists('..\..\..\packages\Microsoft.Windows.ImplementationLibrary.1.0.220914.1\build\native\Microsoft.Windows.ImplementationLibrary.targets')" />
|
||||
</ImportGroup>
|
||||
<Target Name="EnsureNuGetPackageBuildImports" BeforeTargets="PrepareForBuild">
|
||||
<PropertyGroup>
|
||||
|
@ -58,5 +63,6 @@
|
|||
</PropertyGroup>
|
||||
<Error Condition="!Exists('..\..\..\packages\Microsoft.Windows.CppWinRT.2.0.221104.6\build\native\Microsoft.Windows.CppWinRT.props')" Text="$([System.String]::Format('$(ErrorText)', '..\..\..\packages\Microsoft.Windows.CppWinRT.2.0.221104.6\build\native\Microsoft.Windows.CppWinRT.props'))" />
|
||||
<Error Condition="!Exists('..\..\..\packages\Microsoft.Windows.CppWinRT.2.0.221104.6\build\native\Microsoft.Windows.CppWinRT.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\..\..\packages\Microsoft.Windows.CppWinRT.2.0.221104.6\build\native\Microsoft.Windows.CppWinRT.targets'))" />
|
||||
<Error Condition="!Exists('..\..\..\packages\Microsoft.Windows.ImplementationLibrary.1.0.220914.1\build\native\Microsoft.Windows.ImplementationLibrary.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\..\..\packages\Microsoft.Windows.ImplementationLibrary.1.0.220914.1\build\native\Microsoft.Windows.ImplementationLibrary.targets'))" />
|
||||
</Target>
|
||||
</Project>
|
|
@ -9,3 +9,5 @@
|
|||
#include <filesystem>
|
||||
#include <fstream>
|
||||
|
||||
#include <common/logger/logger.h>
|
||||
#include <wil/filesystem.h>
|
||||
|
|
|
@ -3,6 +3,7 @@
|
|||
#include <windows.h>
|
||||
#include <winrt/base.h>
|
||||
#include <wil/resource.h>
|
||||
#include <wil/filesystem.h>
|
||||
#include <ProjectTelemetry.h>
|
||||
#include <common/logger/logger.h>
|
||||
|
||||
|
|
|
@ -13,8 +13,9 @@
|
|||
#include <ShellScalingApi.h>
|
||||
#include <strsafe.h>
|
||||
#include <TraceLoggingActivity.h>
|
||||
#include <wil\resource.h>
|
||||
#include <wil\result.h>
|
||||
#include <wil/filesystem.h>
|
||||
#include <wil/resource.h>
|
||||
#include <wil/result.h>
|
||||
#include <winrt/windows.foundation.h>
|
||||
#include <psapi.h>
|
||||
#include <shared_mutex>
|
||||
|
|
|
@ -9,6 +9,7 @@
|
|||
|
||||
#include <wil/resource.h>
|
||||
#include <wil/com.h>
|
||||
#include <wil/filesystem.h>
|
||||
|
||||
#include <string_view>
|
||||
#include <optional>
|
||||
|
|
Загрузка…
Ссылка в новой задаче