Control game ticks/frames of updates and rendering separately
I think sourcing the game-loop out is basically a good idea to improve separation of concerns. But I would go farther: I would implement a strategy pattern which makes the behavior of the game loop exchangeable. Futhermore I would source out the loop itself, too.

public interface IGameLoop{
    void Start();
    void Stop();
}
public interface IUpdateBahvior
{
    bool TryUpdate();
}
public interface IRenderBehavior
{
    bool TryRender();
}


Example implementation: 

class SynchronGameLoop : IGameLoop
{
    private bool _isRunning;
    private readonly IUpdateBehavior _updateBehavior;
    private readonly IRenderBehavior _renderBehavior;

    public SynchronGameLoop(IUpdateBehavior updateBehavior, IRenderBehavior renderBehavior){
        _updateBehavior = updateBehavior;
        _renderBehavior = IRenderBehavior ;
    }

    public void Start(){
        if(_isRunning) return;
        while(_isRunning){
            _updateBehavior.TryUpdate();
            _renderBehavior.TryRender();
        }
    }
    public void Stop()
    {
        _running = false;
    }
}

class AsyncGameLoop : IGameLoop ...

class StatisticProvidingGameLoop: IGameLopp ...


This system offers you the possibility to exchange the game loop behavior at run-time. So If you decide to implement a game loop that offers statistic information(update count, update time, render count) for debugging purpose, you free to exchange this, without altering your code. 

The separation into two *behavior interface provide the possibility to implement completely independent strategies, for this two functionality. But if you wish to, one class can implement both interfaces and can make the functionality dependent on each other. So while implementing your engine, you don't define what kind of game loop and update/render behavior is finally used. For example in XNA, you can switch between fixed time steps and variable one. All this is easily possible with the strategy pattern.