* Only use async marshalling to renderer sync context when necessary
Note that the lifecycle methods already take care of capturing the correct sync context, so continuations will already be serialized.
Avoiding an extra layer of asynchrony keeps the semantics of rendering closer to the WebAssembly cases, and will fix a range of intermittent errors in the wild.
* Add E2E test of triggering rendering from outside the sync context
* Actually throw if attempting to render from incorrect sync context
* Add "Dispatch" API
* Handle dispatch within dispatch. Also test Dispatch on WebAssembly.
* Avoid heap allocation
* Simplify E2E test
* Replace Dispatch() with Invoke() and InvokeAsync()
* Add E2E test to validate async execution order
* Clean up