更好的循环方式来检测变化

时间:2010-03-30 18:09:24

标签: c# memory

截至目前,我正在使用while(true)方法来检测内存中的变化。这个问题是它会破坏应用程序的性能。我有一个30个指针的列表,需要尽快检查更改,而不会牺牲巨大的性能损失。有人有这方面的想法吗?

编辑**这样做的想法是在运行在线射击游戏时检测由某些应用程序引起的内存变化。不是真的反作弊,但它是沿着这些方向。

memScan = new Thread(ScanMem);

public static void ScanMem()
        {            
            int i = addy.Length;
            while (true)
            {
                Thread.Sleep(30000); //I do this to cut down on cpu usage
                for (int j = 0; j < i; j++)
                {
                    string[] values = addy[j].Split(new char[] { Convert.ToChar(",") });
                    //MessageBox.Show(values[2]);
                    try
                    {
                        if (Memory.Scanner.getIntFromMem(hwnd, (IntPtr)Convert.ToInt32(values[0], 16), 32).ToString() != values[1].ToString())
                        {
                            //Ok, it changed lets do our work
                            //work 
                            if (Globals.Working)
                                return;                            
                            SomeFunction("Results: " + values[2].ToString(), "Memory");
                            Globals.Working = true;
                        }//end if
                    }//end try
                    catch { }
                }//end for
            }//end while
        }//end void

4 个答案:

答案 0 :(得分:3)

为什么要通过指针循环查找更改?为什么不使用基于事件的机制?

我认为指针指向一个类?让那个类在每次变为“脏”时引发一个事件,然后有一个监督类来监视类并处理所引发的任何事件。

答案 1 :(得分:2)

您无需一次检查所有元素。您可以实现流水线操作。因此,在每次迭代中,您最终一次只能检查一个元素。这样您就不会遇到任何与性能相关的问题,最终会检查30次迭代中的所有元素。因此,只需减少睡眠并将其移动到内部for循环中,如下所示。我认为应该提高你的表现。

memScan = new Thread(ScanMem);

public static void ScanMem()
    {            
        int i = addy.Length;

        while (true)
        {
            for (int j = 0; j < i; j++)
            {

                Thread.Sleep(10000); // Reduce sleep

                string[] values = addy[j].Split(new char[] { Convert.ToChar(",") });
                //MessageBox.Show(values[2]);
                try
                {
                    if (Memory.Scanner.getIntFromMem(hwnd, (IntPtr)Convert.ToInt32(values[0], 16), 32).ToString() != values[1].ToString())
                    {
                        //Ok, it changed lets do our work
                        //work 
                        if (Globals.Working)
                            return;                            
                        SomeFunction("Results: " + values[2].ToString(), "Memory");
                        Globals.Working = true;
                    }//end if
                }//end try
                catch { }
            }//end for
        }//end while
    }//end void

答案 2 :(得分:1)

假设没有办法让受监控的代码将事件放在脏上,这几乎是最好的解决方案。

Nit-picking(因为我希望这些只是针对片段进行修剪):

  • 我希望你有充分的理由在循环中调用string.Split。显然,如果addy变量没有改变,最好存储int数组并使用
  • 类似地,int比较比字符串比较
  • 更好
  • 我真的希望你不要只是忽略那样的例外

修复这些(假设它们可以在实际代码中解决)将有助于略微提高性能。另外,我真的怀疑你的暂停需要30秒,你可能只需要暂停一秒就可以减少CPU。

答案 3 :(得分:1)

Cycle的变量j仅用于从 addy 中进行选择。也许,除了轮询之外,最好将 for()更改为 Parallel.For()

PS。我不知道“重” SomeFunction Memory.Scanner 是多么(可能它们也改变了一些全局状态)以及你同时执行的其他操作。