Home > Back-end >  Why am I getting stackoverflow on my System.Timers.Timer through a different thread?
Why am I getting stackoverflow on my System.Timers.Timer through a different thread?

Time:03-20

basically, I made a System.Timers.Timer timer, and I used a method to open a new thread and run the timer. Everytime when something changes, like when I am not in a game, it changes the label, and then two seconds later it crashes. I tried to use Dispatcher.Invoke() to prevent getting the "different thread" error, it successfully changes the label and then crashes, I also used Dispatcher.BeginInvoke(), which got me an AccessException or something. I'm trying to find a way to make this not crash, and make it run smoothly when changing a different label.

System.Timers.Timer tm = new System.Timers.Timer();
System.Timers.Timer tma = new System.Timers.Timer();
public ElapsedEventHandler Injection()
        {
            if (inject == true)
            {
                Dispatcher.Invoke(new Action(delegate
                {
                    tm.Start();
                    tma.Stop();
                    StatusLabel.Content = "Injecting..".ToString();
                }));
            }
            else if (api.currentlyinjecting == true)
            {
                Dispatcher.Invoke(() =>
                {
                    if (StatusLabel.Content.ToString() == "Injecting..")
                    {

                    }
                    else
                    {
                        StatusLabel.Content = "Injecting..";
                    }
                });
                tm.Start();
                tma.Stop();
            }
            else
            {
                if (api.AlreadyInjected() == false)
                {
                    Dispatcher.Invoke(() =>
                    {
                        if (StatusLabel.Content.ToString() == "Not Injected")
                        {

                        }
                        else
                        {
                            StatusLabel.Content = "Not Injected";
                        }
                    });
                }
                else
                {
                    Dispatcher.Invoke(() =>
                    {
                        if (StatusLabel.Content.ToString() == "Not Injected")
                        {

                        }
                        else
                        {
                            StatusLabel.Content = "Not Injected";
                        }
                    });
                }
            }
            return Injection();
        }
        public ElapsedEventHandler Injection2()
        {
            if (api.AlreadyInjected())
            {
                if (StatusLabel.Content.ToString() == "Injected")
                {
                    if (api.AlreadyInjected() == false)
                    {
                        tma.Start();
                        tm.Stop();
                    }
                }
                else
                {
                    Dispatcher.Invoke(() =>
                    {
                        StatusLabel.Content = "Injected";
                    });
                }
            }
            return Injection2();
        }

CodePudding user response:

You are calling return Injection(); at the end of the Injection method, this will result in a never ending recursion.

In software, a stack overflow occurs if the call stack pointer exceeds the stack bound. The call stack may consist of a limited amount of address space, often determined at the start of the program. source

Simply said: When calling a method, current variables/arguments are pushed onto the stack (some memory bound to the thread) and will be cleaned up when exit that method. If you call the method within the method over and over, the used memory will stack-up, until you exceed it's size. You program will crash with a stackoverflow. (this isn't an exception you can try/catch)

It's the same for Injection2.

The Injection method should be called by the timer, not by your method.


You should use the DispatcherTimer for WPF wich will result in much cleaner code, because you don't need to Invoke.

If you tell a bit more about the API, we might give a better example.

  • Related