Are there best practices for implementing an asynchronous game engine cycle?

I implemented the game engine loop as follows:

public static Boolean Start ( ) { if (hasBoard) { // start engine on worker thread asyncTask = new AsyncResult ( stopEngine, asyncTask ); isRunning = ThreadPool.QueueUserWorkItem ( startEngine, asyncTask ); if (isRunning) { Console.WriteLine ( "[{0}] Engine started", DateTime.Now.ToString ( "hh:mm:ss" ) ); } else { Console.WriteLine ( "[{0}] Engine failed to start", DateTime.Now.ToString ( "hh:mm:ss" ) ); } } return isRunning; } public static void Stop ( ) { Console.WriteLine ( "[{0}] Engine stopping", DateTime.Now.ToString ( "hh:mm:ss" ) ); asyncTask.SetAsCompleted ( null, false ); } private static void startEngine ( Object task ) { while (!( (IAsyncResult)task ).IsCompleted) { Thread.Sleep ( 10000 ); Console.WriteLine ( "[{0}] Engine running", DateTime.Now.ToString ( "hh:mm:ss" ) ); } } private static void stopEngine ( IAsyncResult iaResult ) { // clean up resources Console.WriteLine ( "[{0}] Engine stopped", DateTime.Now.ToString ( "hh:mm:ss" ) ); isRunning = false; } 

I use the AsyncResult class recommended by Jeff Richter in his article, Implementing the CLR Asynchronous Programming Model . To be able to stop the engine from the user interface, the implementation I used was slightly different from the standard asynchronous template. This implementation works as expected, but when I digress from standard practice, I return to the SO community to ensure that I am doing everything right.

Are there any problems with this implementation that everyone can see?

+7
source share
2 answers

Since this sounds like a project that you control over, I suggest you use APC and use the model with Task introduced in .NET4. This is the recommended approach for .NET4 instead of APM. The Task class is part of the parallel task library ( TPL ), but it is great for these basic asynchronous tasks, such as good.

 private CancellationTokenSource cts; public void StartEngine() { if (cts == null) { cts = new CancellationTokenSource(); Task.Factory.StartNew(() => GameLoop(cts.Token), cts.Token); } } private void GameLoop(CancellationToken token) { while (true) { token.ThrowIfCancellationRequested(); Thread.Sleep(1000); Debug.WriteLine("working..."); } } public void StopEngine() { if (cts != null) { cts.Cancel(); cts = null; } } 
+11
source

I would say that he meant that tasks are short-lived when using a thread pool, since the number of threads in it is limited.

In your case, I would use BackgroundWorker because you mentioned winforms. BW handles the synchronization for you and therefore can update the GUI without using InvokeRequired, etc.

+2
source

All Articles