开发者

Better way of looping to detect change

As of now I'm using a while(true) method to detect changes in memory. The problem with this is it's kill the applications performance. I have a list of 30 pointers that need checked as rapidly as possible for changes, without sacrificing a huge performance loss. Anyone have ideas on this?

EDIT** The idea of this is to detect changed in memory caused by certain applications while running an online shooter game. Not really an anti-cheat, but it's along those lines.

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(开发者_JAVA技巧), "Memory");
                            Globals.Working = true;
                        }//end if
                    }//end try
                    catch { }
                }//end for
            }//end while
        }//end void


why loop through the pointers to find changes? why not use an event based mechanism?

i presume the pointers are pointing at a class? have that class raise an event each time it becomes 'dirty' and then have a supervisory class that monitors the classes and handles any events that are raised.


You need not check all the elements at once. You can implement pipelining. So that in every iteration you end up checking only one element at a time. This way you will not face any performance related issues and you will end up checking all elements in 30 iterations. So just reduce your sleep and move it inside the inner for loop as shown below. I think should improve your performance.

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


Assuming that there's no way to get the monitored code to throw events on-dirty, this is approximately the best solution available.

Nit-picking (since I hope these were just trimmed for the snippet):

  • I hope that you have a good reason to call string.Split inside the loop like that. Obviously, if the addy variable is not changing, it would be better to store int arrays and use that
  • Similary, an int comparison would be better than a string comparison
  • I really hope you aren't just ignoring exceptions like that

Fixing those (assuming they can be addressed in the real code) would help performance marginally. Also, I really doubt that your pause needs to be 30 seconds, you could probably cut CPU almost as much with just a 1 second pause.


Cycle's variable j is only used to select from addy. Perhaps, aside from polling, it would be good idea to change for() to Parallel.For() ?

PS. I don't know how "heavy" SomeFunction and Memory.Scanner are (perhaps they also change some global state) and what other operations you do perform at the same time.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜