While all the Activity objects run asynchronously, they do not execute on separate threads, so each successive activity only executes when the previously scheduled activity completes or goes idle. If none of the child activities of this activity go idle, this activity execute in the same way that a Sequence activity does.
Sleep (or Delay activity) is async, so it releases control (goes idle).
ExtractData is also async, so it also releases control (goes idle).
Hence with that execution context Parallel will work “as expected”.
Check with attached file - first parallel has no asyncs (Message boxes used as blocker examples), second parallel has asyncs (delays of 1ms). Observe that branches switch when they encounter an async activity (clearly visible when running in debug and stepping).
ParallelTest.xaml (19.6 KB)
If you use invokes, you’re introducing threading (or mult-process, if using Isolated), thus execution contextes are completely separate and you don’t need to worry if something is async or not, since it’s no longer running in same thread/process (and thus can’t block itself).
Do keep in mind that if used incorrectly, multithreading and multiprocessing might introduce issues, including (but not limited to):
- WIth multithreading most common error is that one parallel execution changes something that the second one was using in unexpected way or moment, producing hard to track errors
- With multiprocessing all data passed between them has to be serializable (since they don’t share same memory space)
- WIth both it is possible to have deadlocks (that is - both execution contexts are waiting for each other and none of them does anything, essentially creating a hang in the application without any error message)