public HttpServerExchange dispatch(final Executor executor, final Runnable runnable) {
        if (isInCall()) {
            if (executor != null) {
                this.dispatchExecutor = executor;
            }
            state |= FLAG_DISPATCHED;
            if(anyAreSet(state, FLAG_SHOULD_RESUME_READS | FLAG_SHOULD_RESUME_WRITES)) {
                throw UndertowMessages.MESSAGES.resumedAndDispatched();
            }
            this.dispatchTask = runnable;
        } else {
            if (executor == null) {
                getConnection().getWorker().execute(runnable);
            } else {
                executor.execute(runnable);
            }
        }
        return this;
    }
public HttpServerExchange dispatch ( final Executor executor , final Runnable runnable ) { if ( isInCall ( ) ) { if ( executor != null ) { this . dispatchExecutor = executor ; } state |= FLAG_DISPATCHED ; if ( anyAreSet ( state , FLAG_SHOULD_RESUME_READS | FLAG_SHOULD_RESUME_WRITES ) ) { throw UndertowMessages . MESSAGES . resumedAndDispatched ( ) ; } this . dispatchTask = runnable ; } else { if ( executor == null ) { getConnection ( ) . getWorker ( ) . execute ( runnable ) ; } else { executor . execute ( runnable ) ; } } return this ; }
Dispatches this request to the given executor. Once the call stack returns
the given runnable will be submitted to the executor.
<p>
In general handlers should first check the value of {@link #isInIoThread()} before
calling this method, and only dispatch if the request is actually running in the IO
thread.

@param runnable The task to run
@throws IllegalStateException If this exchange has already been dispatched