我已经实现了如下游戏引擎循环:
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;
}
我正在使用Jeff Richter在其文章Implementing the CLR Asynchronous Programming Model中推荐的AsyncResult
课程。为了能够从UI停止引擎,我使用的实现与标准异步模式略有不同。这个实现按预期工作,但是当我偏离标准实践时,我回到SO社区以确保我以正确的方式做事。
这个实现是否存在任何人都能看到的问题?
答案 0 :(得分:11)
由于这听起来像是一个你可以控制的项目,我建议你抛弃APM并使用.NET4中提供的基于Task
的模型。这是.NET4而不是APM的推荐方法。 Task
类是任务并行库(TPL)的一部分,但它也非常适合这些基本的异步作业。
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;
}
}
答案 1 :(得分:2)
我会说,这意味着在使用线程池时任务是短暂的,因为它中的线程数是有限的。
在你的情况下,我会使用BackgroundWorker,因为你提到了winforms。 BW为您处理同步,因此无需使用InvokeRequired等即可更新GUI。