7

我已经实现了一个游戏引擎循环,如下所示:

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;
}

我正在使用AsyncResultJeff Richter 在他的文章实现 CLR 异步编程模型中推荐的类。为了能够从 UI 中停止引擎,我使用的实现有点偏离标准的异步模式。此实现按预期工作,但是当我偏离标准实践时,我会回到 SO 社区以确保我以正确的方式做事。

此实现是否存在任何人都可以看到的问题?

4

2 回答 2

11

由于这听起来像是您可以控制的项目,我建议您放弃 APM 并使用Task.NET4 中提供的基于 - 的模型。这是 .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;
    }
}
于 2011-01-02T06:08:11.693 回答
2

我会说这意味着使用线程池时任务是短暂的,因为其中的线程数量是有限的。

在你的情况下,我会使用 BackgroundWorker,因为你提到了 winforms。BW 为您处理同步,因此无需使用 InvokeRequired 等即可更新 GUI。

于 2011-01-02T06:17:16.180 回答