首先,让我们制作一个可重现的代码版本。这不是实现您正在做的事情的最佳方式,而是向您展示代码中正在发生的事情!
我将保持代码与您的代码几乎相同,除了我将使用简单的 int 而不是您的 JobDto 并且在完成工作后 Execute() 我将写入一个我们可以验证的文件之后。这是代码
public class SomeMainClass
{
public void StartProcessing()
{
var jobList = Enumerable.Range(1, 10).ToArray();
var tasks = new Task[10];
//[1] start 10 jobs, one-by-one
for (int i = 0; i < jobList.Count(); i++)
{
tasks[i] = ProcessJob(jobList[i]);
}
//[4] here we have 10 awaitable Task in tasks
//[5] do all other unrelated operations
Thread.Sleep(1500); //assume it works for 1.5 sec
// Task.WaitAll(tasks); //[6] wait for tasks to complete
// The PROCESS IS COMPLETE here
}
public async Task ProcessJob(int jobTask)
{
try
{
//[2] start job in a ThreadPool, Background thread
var T = Task.Factory.StartNew(() =>
{
JobWorker jobWorker = new JobWorker();
jobWorker.Execute(jobTask);
});
//[3] await here will keep context of calling thread
await T; //... and release the calling thread
}
catch (Exception) { /*handle*/ }
}
}
public class JobWorker
{
static object locker = new object();
const string _file = @"C:\YourDirectory\out.txt";
public void Execute(int jobTask) //on complete, writes in file
{
Thread.Sleep(500); //let's assume does something for 0.5 sec
lock(locker)
{
File.AppendAllText(_file,
Environment.NewLine + "Writing the value-" + jobTask);
}
}
}
只运行StartProcessing() 之后,这就是我在文件中得到的内容
Writing the value-4
Writing the value-2
Writing the value-3
Writing the value-1
Writing the value-6
Writing the value-7
Writing the value-8
Writing the value-5
所以,8/10 的工作已经完成。显然,每次运行时,数量和顺序都可能发生变化。但是,关键是,所有的工作都没有完成!
现在,如果我取消注释步骤 [6] Task.WaitAll(tasks);,这就是我在文件中得到的内容
Writing the value-2
Writing the value-3
Writing the value-4
Writing the value-1
Writing the value-5
Writing the value-7
Writing the value-8
Writing the value-6
Writing the value-9
Writing the value-10
所以,我所有的工作都在这里完成了!
为什么代码会这样,已经在 code-cmets 中解释过了。需要注意的主要事项是,您的任务在基于Background 的线程中运行。所以,如果你不等待它们,它们将在 MAIN 进程结束并且主线程退出时被杀死!
如果您仍然不想在那里等待任务,您可以从第一个方法返回任务列表,并在流程结束时返回 await 任务,类似这样
public Task[] StartProcessing()
{
...
for (int i = 0; i < jobList.Count(); i++)
{
tasks[i] = ProcessJob(jobList[i]);
}
...
return tasks;
}
//in the MAIN METHOD of your application/process
var tasks = new SomeMainClass().StartProcessing();
// do all other stuffs here, and just at the end of process
Task.WaitAll(tasks);
希望这能消除所有困惑。