5,927
社区成员




江湖救急,江湖救急,江湖救急
在多线程中调用了一个dll编写的插件,创建了一个定时器createTimerQueueTimer,结果忘记删除了,导致改定时器 一直在执行,
现在想把这个定时器删除了,不知道咋个搞?麻烦高手解决一下 ,红包 奉上
能回这样帖子的都是高手啊。
我是来凑数的,我不明白的是,DLL重搞一下不行吗?
不知道创建的定时器队列的句柄?那就是没有源码,你要搞别人的DLL,关闭定时检查什么什么事件之类的?估计你的水平还稍微欠一点点。
没有句柄怎搞呢,简单说就是:
调用NtQuerySystemInformation,查询类型SystemHandleInformation
对返回的缓冲区的每个handle
调用NtQueryObject,查询的对象信息类ObjectTypeInformation
返回结构中有它的类型名字符串
然后你判断是否需要CloseHandle即可~~~
兄弟,能给个删除的代码吗?dll我自己可以搞定
如果你在使用 Embarcadero RAD Studio XE10.1 中创建了一个名为 createTimerQueue 的 DLL 函数,但忘记了删除它,可以通过以下步骤进行处理:
编写一个修复DLL函数的程序:创建一个新的 DLL,其中包含一个函数,用于删除或清理之前创建的 createTimerQueue。这种方法通常需要对你的原始 DLL 的代码和功能有较深的理解。你需要确保新的 DLL 可以正确识别和处理 createTimerQueue 的创建,并执行适当的清理操作。
或者创建一个新的DLL.
在Windows中,如果你创建了一个定时器(TimerQueueTimer),但是忘记删除它,定时器会一直执行。要删除这个定时器,可以使用DeleteTimerQueueTimer函数。下面是如何删除定时器的步骤:
#include <windows.h>
// 定时器句柄
HANDLE hTimer = NULL;
// 定时器回调函数
void CALLBACK TimerRoutine(PVOID lpParam, BOOLEAN TimerOrWaitFired)
{
// 定时器任务
}
void CreateMyTimer()
{
CreateTimerQueueTimer(
&hTimer, // 定时器句柄
NULL, // 默认的定时器队列
TimerRoutine, // 定时器回调函数
NULL, // 传递给回调函数的参数
0, // 定时器首次触发的延迟时间(毫秒)
1000, // 定时器间隔时间(毫秒)
0 // 定时器选项
);
}
2. 删除定时器
要删除定时器,可以使用DeleteTimerQueueTimer函数。需要注意的是,DeleteTimerQueueTimer会等待所有正在运行的回调函数执行完毕,然后再删除定时器。
void DeleteMyTimer()
{
if (hTimer != NULL)
{
// 删除定时器
if (!DeleteTimerQueueTimer(NULL, hTimer, INVALID_HANDLE_VALUE))
{
// 删除失败
printf("DeleteTimerQueueTimer failed with error %d\n", GetLastError());
}
else
{
// 成功删除定时器
printf("Timer successfully deleted\n");
}
hTimer = NULL;
}
}
3. 在多线程环境中删除定时器
在多线程环境中,需要确保在删除定时器时不会与其他线程发生竞争。可以使用互斥锁(Mutex)或临界区(Critical Section)来保护定时器的创建和删除操作。
#include <windows.h>
#include <stdio.h>
HANDLE hTimer = NULL;
CRITICAL_SECTION cs;
void CALLBACK TimerRoutine(PVOID lpParam, BOOLEAN TimerOrWaitFired)
{
// 定时器任务
}
void CreateMyTimer()
{
EnterCriticalSection(&cs);
CreateTimerQueueTimer(
&hTimer, // 定时器句柄
NULL, // 默认的定时器队列
TimerRoutine, // 定时器回调函数
NULL, // 传递给回调函数的参数
0, // 定时器首次触发的延迟时间(毫秒)
1000, // 定时器间隔时间(毫秒)
0 // 定时器选项
);
LeaveCriticalSection(&cs);
}
void DeleteMyTimer()
{
EnterCriticalSection(&cs);
if (hTimer != NULL)
{
// 删除定时器
if (!DeleteTimerQueueTimer(NULL, hTimer, INVALID_HANDLE_VALUE))
{
// 删除失败
printf("DeleteTimerQueueTimer failed with error %d\n", GetLastError());
}
else
{
// 成功删除定时器
printf("Timer successfully deleted\n");
}
hTimer = NULL;
}
LeaveCriticalSection(&cs);
}
int main()
{
InitializeCriticalSection(&cs);
CreateMyTimer();
// 模拟一些操作
Sleep(5000);
DeleteMyTimer();
DeleteCriticalSection(&cs);
return 0;
}
在这个例子中,使用了临界区来保护对定时器句柄的访问,确保在多线程环境中安全地创建和删除定时器。你可以根据你的实际情况选择合适的同步机制,如互斥锁或事件。
既然是“忘记删除了”,那就把删除加上吧。
我很同意,话说发15个字的评论能获得积分,我也试一试
定位定时器: 首先,检查代码中是否有一个全局变量或类成员保存了对定时器的引用,这可能是Windows::Threading::TimerQueueTimer或类似对象。
获取句柄或ID: 找到定时器后,你可能需要它的句柄(如果库提供了这样的接口)或者它的ID来停止它。这通常可以通过定时器对象的成员函数获取。
取消定时器: 使用获得的句柄或ID,调用cancel()、stop()或类似的方法来停止定时器。这取决于库的具体实现,例如在Windows API中可能是CloseHandle(timerHandle),而在WinRT中可能是timer.Cancel()。
清理资源: 如果定时器对象是动态分配的,记得将其从内存中释放,以防止内存泄漏。
处理异常: 在尝试取消定时器时,确保捕获任何可能出现的异常,如找不到句柄或无效操作。
日志和调试: 为了解决这类问题,记录相关的日志信息以便于追踪和解决问题。
如果你在DLL中无法直接操作,可能需要通过插件提供的API或者通知机制来请求父进程或管理器停止定时器。