I suppose your question does not include change detection, as your sample only concerns QgsMapCanvas.refresh()
Instead you have to call QgsRasterLayer.triggerRepaint()
If your layer is called myLayer:
myLayer.setCacheImage( None )
myLayer.triggerRepaint()
The same method exists for vector layers as well.
For low overhead change detection I'd propose looking into the following (unfortunately platform specific) API's