Asynchronous dispatch queue
Remove redundant comments
You added a lot of comments to the code, but many of them are not very useful. Comments should be used to explain what the code does if this is not clear from reading the code itself. But for example:
std::queue&lt;Task&gt; _toDo;

I can see just from this line of code that this is a queue of tasks to be done, so the comment you wrote doesn't add any new information to this. Adding unnecessary comments just increases the noise to signal ratio, and actually makes the code less readable.
Avoid starting names with underscores
The C++ standard reserves some names starting with underscores. Unless you want to learn the exact rules, I recommend you don't start any names with an underscore, but instead use the prefix m_ or a single underscore as a suffix.
Avoid manually locking and unlocking mutexes
I recommed you just use a lock guard without std::defer_lock_t to lock those regions of code that need exclusive access to the data structures. So in MainThread(), I would write:
while (true) {
    std::function&lt;void(void)&gt; task;

    {
        std::unique_lock lock{_mutex};
        _signal.wait_for(lock, []{ return _stop || !_toDo.empty(); });

        if (_stop &amp;&amp; _toDo.empty())
            break;

        task = std::move(_toDo.front());
        _toDo.pop();        
    }

    task();
}

Notify without the lock held
While your code is correct, it is slightly more efficient to call notify_one() if you don't hold the lock. So for example, in the destructor you can write:
~WorkerThread() {
    {
        std::unique_lock lock{_mutex};
        _stop = true;
    }

    _signal.notify_one();
    _thread.join();
}