• 0

BackgroundWorker issue


Question

I am writing a little game (for school, hence the mandatory nonsensical design choices). The top-level component is a Winforms C# application. This is just supposed to provide a window, some basic menus and redirect input events to a C++ dll that does all the rendering and game logic processing.

I'm trying to see where I'm supposed to put my game loop in there. I assume the basic loop has to be in C#, and call native methods like update() and draw(). Since I don't want to stall the GUI, I created a background worker and passed it this method:

        void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e) {
            CycleTimer.TriggerUpdate += CycleTimer_TriggerUpdate;
            CycleTimer.TriggerDraw += CycleTimer_TriggerDraw;
            CycleTimer.Start(30);
            while (true) {
                CycleTimer.Update();
            }
        }

... where CycleTimer is my own class that I've used in a previous game entirely in C# and it was working really well. However I wasn't hosting it in a WinForms app. Now in this situation, I've noticed Update() is called every 25 milliseconds. This is completely unacceptable. It should be called at least every millisecond (and it should even be MUCH faster than that on my pc). Even when I comment out its body entirely so that it is merely called and exit, doing nothing, it is still called no more often than once every 25 milliseconds.

I suppose this is due to backgroundWorker being a somewhat low priority thread? Where is my approach wrong? I'm open to suggestions that deviate a lot from what I've did there. For instance if there was a way to manage the game loop in the C++ dll only, without stalling the WinForms host, that would be great.

Edited by Dr_Asik
Link to comment
https://www.neowin.net/forum/topic/934610-backgroundworker-issue/
Share on other sites

7 answers to this question

Recommended Posts

  • 0

Mk small update: I've replaced my background worker method with this:

        void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e) {
            var stopWatch = Stopwatch.StartNew();
            while (true) {
                Console.WriteLine(stopWatch.ElapsedTicks);
            }
        }

Here's a sample of the output:

6441918
6441929
6441941
6441952
6441964
6441977
6441989
6442002
6442015
6442027
7010387 WTF?!
7010427
7010444
7010461
7010478
7010494
7010510
7010527
7010544
7010561
7010577

So basically it is called super-often and then there are long random pauses every now and then.

  • 0

Ok nvm all this. The variability observed is normal and I can compensate for it with an intelligent game loop. I get very stable results using a compensating algorithm. Also, the long delays I had observed at the beginning stemmed from doing a Console.WriteLine every time through the loop, which would result in a deluge of output and create some delays.

All is well. I use a normal System.Threading.Thread now but I guess BackgroundWorker would have done the trick too.

  • 0

6441918
6441929
6441941
6441952
6441964
6441977
6441989
6442002
6442015
6442027
7010387 WTF?!
7010427
7010444
7010461
7010478
7010494
7010510
7010527
7010544
7010561
7010577

So basically it is called super-often and then there are long random pauses every now and then.

If this was Java, my first thought would be "garbage collection". Everyone I know that runs a production Java service has nothing but bad things to say about it. You're using .NET, but I can only assume it has a similar problem.

  • 0

If this was Java, my first thought would be "garbage collection". Everyone I know that runs a production Java service has nothing but bad things to say about it. You're using .NET, but I can only assume it has a similar problem.

It might also just be the OS deciding that my thread doesn't get CPU time for a few thousand ticks, and the same issue would happen in a non-gced environment.
  • 0

It might also just be the OS deciding that my thread doesn't get CPU time for a few thousand ticks, and the same issue would happen in a non-gced environment.

Yep, you'll notice the same thing in native code. Create 2 threads that do nothing other than increment an integer and you'll see marked variation in the progress of each thread.
This topic is now closed to further replies.
  • Recently Browsing   0 members

    • No registered users viewing this page.
  • Posts

    • It is silly there is no simple way to check whether this profile has been activated. CFRs are normal, but trying to even hide the fact if it's on / off seems silly, especially for something so user-facing. Surely Microsoft is "proud" of their engineering efforts on this one and ought to display it somwhere in the GUI.
    • Many Linux distros are not known for excellent battery life, so I'm not sure that is the best example. A more apt example may be Apple, but Apple's CPUs are simply far more efficient than Intel & AMD at single-threaded tasks like these, so "boosting" is not as power-hungry and less heat-inducing. Not to mention Apple will hardly engage P-cores for basic UI tasks; they use a pretty complicated QoS scheme to only activate P-cores for more serious workloads like HTML / JS execution or decompression or application launch. Microsoft is (smartly) doing it for launch, but also for UI tasks, which is the more nonsensical part: why ... do Windows 11's UIs need modern CPUs to boost? It should load so quickly that there's not even time for the CPU to boost.
    • I've not seen any controlled testing and, judging by Microsoft's mentality, within a year, they'll have added so much more bloat, it'll undo any perceptible latency benefit and we'll have boosted the CPU clocks for nothing.
    • It depends: heat soak is a thing. Initially on cold boot-up, the heatsinks & heatpipes are at ambient temp. After heatsinks & heatpipes warm up (through normal usage), they don't immediately cool to ambient temp when the load goes away. So their baseline is higher and the trigger point for fans is much less stress. Add a few more CPU spikes → it's too hot to stay at the same fan RPM → fans get triggered to start up up much sooner / get triggered to ramp much more quickly.
    • Can LibreOffice just shut up and worry about themselves and stop comparing themselves? Do we see Microsoft complaining about euro office?
  • Recent Achievements

    • One Year In
      slackerzz earned a badge
      One Year In
    • One Year In
      highriskpaym earned a badge
      One Year In
    • One Month Later
      highriskpaym earned a badge
      One Month Later
    • Week One Done
      highriskpaym earned a badge
      Week One Done
    • Week One Done
      FBSPL earned a badge
      Week One Done
  • Popular Contributors

    1. 1
      +primortal
      501
    2. 2
      PsYcHoKiLLa
      198
    3. 3
      +Edouard
      156
    4. 4
      Steven P.
      84
    5. 5
      ATLien_0
      71
  • Tell a friend

    Love Neowin? Tell a friend!