<!-- language-all: lang-py -->
I suppose your question does not include change detection, as your sample only concerns QgsMapCanvas.refresh()

Instead you have to call [QgsRasterLayer.triggerRepaint()][1]

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

 - inotify ([pyinotify][2], Linux)
 - FindFirstChangeNotification ([pywin32][3], Windows)


  [1]: http://www.qgis.org/api/classQgsRasterLayer.html#ad2fabc4fdc3bce56d615b5513767eaa9
  [2]: http://pyinotify.sourceforge.net/
  [3]: http://sourceforge.net/projects/pywin32/