patch 8.0.0036
Problem:    Detecting that a job has finished may take a while.
Solution:   Check for a finished job more often (Ozaki Kiichi)
diff --git a/src/os_win32.c b/src/os_win32.c
index 9ff2f7e..d52beb8 100644
--- a/src/os_win32.c
+++ b/src/os_win32.c
@@ -4973,13 +4973,53 @@
     if (!GetExitCodeProcess(job->jv_proc_info.hProcess, &dwExitCode)
 	    || dwExitCode != STILL_ACTIVE)
     {
-	job->jv_status = JOB_ENDED;
 	job->jv_exitval = (int)dwExitCode;
+	if (job->jv_status != JOB_ENDED)
+	{
+	    ch_log(job->jv_channel, "Job ended");
+	    job->jv_status = JOB_ENDED;
+	}
 	return "dead";
     }
     return "run";
 }
 
+    job_T *
+mch_detect_ended_job(job_T *job_list)
+{
+    HANDLE jobHandles[MAXIMUM_WAIT_OBJECTS];
+    job_T *jobArray[MAXIMUM_WAIT_OBJECTS];
+    job_T *job = job_list;
+
+    while (job != NULL)
+    {
+	DWORD n;
+	DWORD result;
+
+	for (n = 0; n < MAXIMUM_WAIT_OBJECTS
+				       && job != NULL; job = job->jv_next)
+	{
+	    if (job->jv_status == JOB_STARTED)
+	    {
+		jobHandles[n] = job->jv_proc_info.hProcess;
+		jobArray[n] = job;
+		++n;
+	    }
+	}
+	if (n == 0)
+	    continue;
+	result = WaitForMultipleObjects(n, jobHandles, FALSE, 0);
+	if (result >= WAIT_OBJECT_0 && result < WAIT_OBJECT_0 + n)
+	{
+	    job_T *wait_job = jobArray[result - WAIT_OBJECT_0];
+
+	    if (STRCMP(mch_job_status(wait_job), "dead") == 0)
+		return wait_job;
+	}
+    }
+    return NULL;
+}
+
     int
 mch_stop_job(job_T *job, char_u *how)
 {