<!-- 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 file change notification I'd propose looking into Qt's [`QFileSystemWatcher`][2], which makes use of [inotify][3] on linux and [similar techniques][6] on [other][5] [platforms][4].

    from PyQt4.QtCore import QFileSystemWatcher

    def refreshLayer():
        myLayer.setCacheImage( None )
        myLayer.triggerRepaint()
    
    watcher = QFileSystemWatcher()
    watcher.addPath( '/path/to/your/raster' )
    watcher.fileChanged.connect( refreshLayer )


Of course this can be combined with an MD5 check as proposed by nickves or a  modification time check with `os.stat` (Nathan W proposal).


  [1]: http://www.qgis.org/api/classQgsRasterLayer.html#ad2fabc4fdc3bce56d615b5513767eaa9
  [2]: http://qt-project.org/doc/qt-4.8/qfilesystemwatcher.html#details
  [3]: http://en.wikipedia.org/wiki/Inotify
  [4]: http://en.wikipedia.org/wiki/Kqueue
  [5]: https://developer.apple.com/library/mac/#documentation/Darwin/Conceptual/FSEvents_ProgGuide/Introduction/Introduction.html
  [6]: http://msdn.microsoft.com/de-ch/library/windows/desktop/aa364417%28v=vs.85%29.aspx