"while(true)"Loop doesent work permanent

Shynex

Member
Joined
Jan 28, 2020
Messages
11
Programming Experience
Beginner
So currently I am programming a c# Steam Bot with the visual Studio add on selenium.
So far it is working pretty well, but the "while (true)" loop just stops after some time.
Sometimes its running like 600 times, but there are also some runs with only 100 iterations.
I highly appreciate every Idea, which could solve my Problem.:)

Thats basicly the Code:

C#:
while (true)
{
    //Click some Buttons
    //Save some Numbers

    if (I like the Item)
    {
        //buyItem();
    }

    Reload_the_Numbers()
    reloadButton.Click();
    wait(5);
}
 
Last edited by a moderator:
So what.

Which part of best practices did you miss me writing? You can either do it the bullshit way, which is the way you're doing it, or do it properly. That's entirely up to you.

Doing some basic research, and you will find developers everywhere telling you that you should run while loops in a background thread or a background worker.

Further, your current code has nothing in it which should be stopping your while loop from running. However, how do you know when a page has refreshed and is ready or not? You need to put more thought into this to provide the necessary logic for checking when the page actually has refreshed or not. Otherwise you won't get the expected result. Currently you're not checking for that. Also, Steam have provided an Steam Community :: Steam Web API Documentation, which you should be using instead of BOT clicking your way around their site which I am sure is in breach of their terms of use.
 
From what I recall from the way Selenium works, Selenium is what runs the main loop and then you can insert "scripts" written either in C#, VB.NET, or JavaScript for Selenium to also execute. This gives Selenium more power that what it was originally written for -- test automation for web pages. With the ability to call other C# or VB.NET, now you can drive more interesting programs which interact more deeply with the OS, or in the case of the OP above, with Steam.

Personally, I would back off from this project. It's been many years now, but as I recall part of the Steam Terms of Service essentially says "no bots allowed". What you are trying to write currently is a bot.
 
Anyway, nothing stands out in the code that you posted in post #1 that would cause things to break out of the loop naturally. The options are:
  • Selenium is terminating the thread that is running that infinite loop.
  • The code within the loop is throwing an exception, effectively terminating the loop and the thread.
  • Selenium implements click() or wait() as co-routines, and those co-routines are not returning control back to that loop.
  • The code for Reload_the_Numbers() executes and never returns back.
  • One of the methods there causes re-entrancy and crashes the stack.
  • One of the methods there indirectly causes recursion and crashes the stack.
 
It would be much easier to just use the API provided by Steam. But I am getting the feeling, that our OP is likely trying to circumvent steam checks, hence the use of a BOT.

As for Selenium; It's not something I've used personally. But it's something I am familiar with. The points I made still stand though.
 
With Selenium, are you calling wait.until .ExecuteScript("return document.readyState").Equals("Complete") before executing more actions in your above steps?

If you are, you could avoid some of the issues on post 19.
 
Äh nope I dont do that. May you explain me what it does?
(And I will try to "open" a new thread for the while(true) loop)
 
Last edited:
Ok I just want to make shure :). Did I create a Independent thread for the while(true) loop?
 
Last edited:
Äh nope I dont do that. May you explain me what it does?
That explains why your loop most likely doesn't run continuously. Search the code I wrote, and you should find many variations for waiting until the pages ready-state is actually completed loading. How can you click on an element of the page which hasn't fully loaded?

Why are you not using the Steam API instead of Selenium?

You could be saving yourself countless hours of work...
 
I know this is a bit of a late reply for this topic, but I was meant to submit this post days ago and I'm only getting to it now. But given that it's been found why your code has stopped is because of how you are estimating when a page is ready, thus likely causing your code to lockup, and also makes this reply a little unrelated to the original problem, however it's not irrelevant to how you should have gone about implementing your code, so here it is.
What @Sheepings is trying to say is that this is "the bad way" to stop that infinite loop:
C#:
void BadRunInfinite()
{
    while (true)
    {
        Console.WriteLine($"{DateTime.Now}");
        Thread.Sleep(1000);
    }
}

void BadWayToStop()
{
    var thread = new Thread(BadRunInfinite);
    thread.Start();

    // Let BadRunInfinite() run for about 5 seconds
    Thread.Sleep(5000);

    // Kill the thread
    thread.Abort();
}

Here's the way to tell the loop to break out:
C#:
ManualResetEvent _stop;

void GoodRunInfinite()
{
    while (true)
    {
        Console.WriteLine($"{DateTime.Now}");

        if (_stop.WaitOne(1000))
            break;
    }
    Console.WriteLine("Done.");
}

void GoodWayToStop()
{
    _stop = new ManualResetEvent(false);
    var thread = new Thread(GoodRunInfinite);
    thread.Start();

    // Let GoodRunInfinite() run for about 5 seconds
    Thread.Sleep(5000);

    // Tell the thread to stop
    _stop.Set();

    // Wait for the thread to exit
    thread.Join();
}
While I was cycling through topics I've been meaning to answer with some code, I found a vague but simple example of how you can manage your thread collection, and how to interact with your thread collection. While your topic was steered in this direction by myself initially, despite it not directly being related to what was stopping your code executing. I thought it be worth sharing this with you and future users, while it will help you to understand how to pass around objects in C#, that; such as your threads collection, and how you can communicate with your threads etc. Anyway, here it is :
C#:
using System;
using System.Collections.Generic;
using System.Threading;

namespace TestConsoleApp
{
    internal static class Program
    {
        private static void Main(string[] args)
        {
            Thread longRunningThread = new Thread(() => Exec_WhileLoop());
            longRunningThread.Name = "LongRunning";
            longRunningThread.Start();
            var ThreadCollection = new List<Thread>();
            ThreadCollection.Add(longRunningThread); /* Using the Thread Collection you can refer some aspects of running threads */
            ThreadCollection = Threads.Thread_Info(ThreadCollection);
        }
        private static void Exec_WhileLoop()
        {
            var i = 1;
            do
            {
                /* Do your work here */
                Console.WriteLine($"Executed {i++} times and continues to run");
                Thread.Sleep(10000);
            }
            while (true);
        }
        public static class Threads
        {
            public static List<Thread> Thread_Info(List<Thread> l_Threads)
            {
                var threads_toRemove = new List<Thread>();
                foreach (Thread current_Thread in l_Threads)
                {
                    if (current_Thread.Name == "LongRunning" && current_Thread.IsAlive)
                    {
                        Console.WriteLine($"Do something with the {current_Thread.Name} thread.");
                        /* This is where you implement your thread stopping as outlined in above post
                         * After you stop the thread, (should you want to) you should remove the thread from your thread collection */
                        threads_toRemove.Add(current_Thread);
                    }
                }
                foreach (Thread toRemove in threads_toRemove)
                {
                    /* Check that your thread is stopped and then remove it from your thread collection. */
                    l_Threads.RemoveAll(r => r.Name == "LongRunning");
                }
                return l_Threads;
            }
        }
    }
}
With the above, you only need to Implement the ManualResetEvent, and then perform a check to cancel the thread. The above is a vague template for doing this. Both you or future readers may find helpful. The only piece needing to be added to line 39 has been demonstrated by @Skydiver here : "while(true)"Loop doesent work permanent - I have posted this because it is better that you learn to execute long running methods in a new thread/background thread, and learn how to talk to those threads through the collections you keep on such threads.
 
Back
Top Bottom