How to monitor render process in a thread-safe manner? I'm currently writing an addon, the purpose of which requires it to render several parts of active scene sequentially, preferably with UI-responsiveness intact. The problem is the UI freezes if I just directly call bpy.ops.render.render(animation=True). I get UI-responsiveness by changing the execution context to "INVOKE_DEFAULT", but then the code won't wait until a render process finished before executing the next one.

Using threading Module

Looking for an alternative, I then use Python's threading.Thread object to encapsulate render function, like this:

def _init_render_thread(self):
    self._render_thread = threading.Thread(
        target=bpy.ops.render.render, kwargs={'animation':True})


... and check the thread object's is_alive method at interval set by a Timer object. Unfortunately it's prone to occasional random crashing, as any thread-related bugs are, so I'm still stuck with this method.

Chaining Handlers

Based on jesterKing's answer, I then chain the render execution using a scene-global property and render handlers with the following code. By chaining, the operator no longer needs to be modal. It's finishing early, then leaving completion to these handlers:

@persistent
def render_pre_handler(dummy):
    props = bpy.context.scene.oha_layout_tools

    if props.render_marker_infos:
        rmi = props.render_marker_infos.pop(0)
        marker_scene_settings(bpy.context, rmi)

@persistent
def render_complete_handler(dummy):
    props = bpy.context.scene.oha_layout_tools

    if props.render_marker_infos:
        rmi = props.render_marker_infos.pop(0)
        marker_scene_settings(bpy.context, rmi)

        bpy.ops.render.render('INVOKE_DEFAULT', animation=True)
    else:
        bpy.app.handlers.render_pre.remove(render_pre_handler)
        bpy.app.handlers.render_complete.remove(render_complete_handler)
        props.marker_infos.clear()
        props.render_marker_infos.clear()


It still doesn't work. The render_complete handler promptly executes even while the render thread itself is still in progress.

Is there any thread-safe way to monitor render process, other than spawning new Blender process?
You can add handlers for render complete process: http://www.blender.org/documentation/blender_python_api_2_67b_release/bpy.app.handlers.html#bpy.app.handlers.render_complete

Use that to flip a flag that you can check in your main code that can check when the current render is ready before starting a new one.

Check also render_post (and render_pre) for usage in your add-on.