You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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
        {
            
        }
    }
}

问题分析与解决

核心问题

  1. 循环内的按键参数不会更新:循环里的m.WParam是触发当前代码的那次按键事件的固定参数,不会自动捕获后续的按键输入。进入循环后,它永远是第一次按下NUM5时的值,自然触发不了终止逻辑。
  2. 同步循环阻塞事件线程:这个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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.09 01:00:26