* This is a possible fix for a case where render work triggered by mouse
movements (such as pixel and vertex picking) can happen faster than it
executes, leading to a backlog of render commands and a noticeable lag
which only gets worse the more you move the mouse until everything
seems to be unresponsive or laggy (especially if you then trigger a
blocking command like event change, which will block the whole UI
until the queued picks happen).
* Since a new pick coming in will override and make redundant the
previous pick, we allow the render commands to do just that. If a new
command comes in, we remove any previous commands with the same tag
and put the command in the first match (this prevents a tagged invoke
always being pushed to the back of the queue).
* This lets us detect when a remote server has been disconnected and
needs to be restarted, as well as alerting the user if this happens in
the middle of a replay session.
* Pinging other hosts means the context switcher is reasonably up to
date if one of them comes up.
* Errors like syntax and runtime errors in python are thrown as
exceptions. So for when we invoke onto the renderer thread to do some
work, we need to be able to catch those exceptions otherwise the whole
program dies. So over the execute, temporarily switch the thread into
a catching-exception mode, which then gets rethrown on the invoker's
thread.
* Note that BeginInvoke shouldn't be used by python since the callback
might happen after the execution has finished (there's no way to wait
at the moment).
* This means that e.g. decimal separator will always be . and similar
effects, which avoids the need to have culture specific formatting or
special-case handling around CSV export etc.