Need to move SetResult out of the lock to prevent deadlock!
Fix the potential deadlock issue introduced by having SetResult inside a lock
Bug: using batch instead of Semaphore to control entering to critical section

should use semaphore to control the concurrency level. if use batch,
when one task completed and batch tasks as a whole did not complete yet,
not new batch will be start to run. which results in degraded
concurrency!