C#持续内存写入终止异常:按下NUM5无法停止内存写入
问题描述
学习C#时遇到按键控制内存写入的问题:按下NUM5开始持续向内存写入值(冻结目标值),再次按下NUM5停止写入。当前代码中,移除if (m.WParam.ToInt32() == 1005)判断后按键功能可正常工作,但保留该判断时,终止写入的break语句完全无法生效。代码如下:
if (checkbox_zfreeze.Checked) { if (m.WParam.ToInt32() == 1005) { isNumpad5Enabled = !isNumpad5Enabled; if (isNumpad5Enabled) { module = swed.GetModuleBase("Game.dll"); IntPtr pp = swed.ReadPointer(module, 0x00A12368, 0x58, 0x210, 0x224, 0x18); float fly = swed.ReadFloat(pp, +0xc3); float originalFlyValue = fly; while (isNumpad5Enabled) { swed.WriteFloat(pp, 0xA0, originalFlyValue); if (m.WParam.ToInt32() == 1005) { swed.WriteFloat(pp, 0xA0, originalFlyValue); isNumpad5Enabled = false; break; } } } else { } } }
问题分析与解决
核心问题
- 循环内的按键参数不会更新:循环里的
m.WParam是触发当前代码的那次按键事件的固定参数,不会自动捕获后续的按键输入。进入循环后,它永远是第一次按下NUM5时的值,自然触发不了终止逻辑。 - 同步循环阻塞事件线程:这个
while循环是同步执行的,会直接卡死当前线程,导致程序根本无法接收第二次按下NUM5的事件信号,后续的终止逻辑连触发机会都没有。
修正方案
方案:后台线程+状态标记控制
把内存写入逻辑放到后台线程,避免阻塞主线程接收按键事件,按键事件只负责切换状态标记:
// 类级成员:声明后台线程变量 private Thread _freezeThread; // 标记变量需加volatile,确保线程间状态可见 private volatile bool isNumpad5Enabled = false; // 按键事件处理逻辑 if (checkbox_zfreeze.Checked) { if (m.WParam.ToInt32() == 1005) { isNumpad5Enabled = !isNumpad5Enabled; if (isNumpad5Enabled) { // 启动后台线程执行冻结操作 _freezeThread = new Thread(() => { var module = swed.GetModuleBase("Game.dll"); var pp = swed.ReadPointer(module, 0x00A12368, 0x58, 0x210, 0x224, 0x18); var originalFlyValue = swed.ReadFloat(pp, +0xc3); while (isNumpad5Enabled) { swed.WriteFloat(pp, 0xA0, originalFlyValue); // 加短延迟,避免过度占用CPU Thread.Sleep(10); } }); _freezeThread.IsBackground = true; _freezeThread.Start(); } else { // 只需要切换标记,后台循环会自动退出 isNumpad5Enabled = false; // 可选:等待线程安全结束 _freezeThread?.Join(100); } } }
关键改进点
- 内存写入逻辑移到后台线程,不会阻塞主线程接收新的按键事件。
- 按键事件仅负责切换
isNumpad5Enabled标记,不再处理循环内的判断。 - 循环内添加
Thread.Sleep(10),大幅降低CPU占用,避免程序无响应。
内容的提问来源于stack exchange,提问作者AndyDE
相关产品推荐
相关产品推荐

