我有一个遗留代码计时器,每2秒运行一次长的数据库更新查询,类似于这个
private void timer_Elapsed(object sender, ElapsedEventArgs e)
{
MySyncMethod();
}
private void MySyncMethod()
{
Task.Run(()=>{Run a long running DB update query});
}
假设我们不需要DB更新结果,那么在上面的代码中不等待任务完成是否有任何含义?
Task.Run(()=>{Update something in DB}).Wait();
根据我的理解,当我们调用Task.Run((时,会从线程池中获取一个新的/可用的线程,并且任务在该线程中运行。因为我们从sync方法调用Task.Run((,所以我们不记得当前的同步上下文,并在任务完成时恢复它,就像我们在异步方法中使用await Task.Run(一样。因此,我的另一个问题是,当任务完成时,后续命令是在任务的线程中执行还是在原始线程中执行,即MySyncMethod((线程?例如,如果我的方法看起来像下面的
private void MySyncMethod((
{
Task.Run(()=>{Run a long running DB update query});
... Do something after Task is completed
}
是。。。做点什么。。。在任务的线程中执行,还是在任务完成后在MySyncMethod((线程中执行?
对不起,MBK,你有很多问题,所以我需要在这里回答:
1.当我们从同步方法调用Task.Run((时,程序控制是否会在Task.Run()
调用后立即返回到被调用方的线程?不,这取决于:
- 如果Task有10个线程并且0->它的队列中有9个查询,然后您调用
Task.Run(()=>{query});
,您的查询将立即运行 - 但是,如果Task的Queue中有10个线程和100个查询,那么您调用
Task.Run(()=>{query});
,查询将不会立即运行,您的查询必须等待91个查询才能完全运行
2.当任务完成时,程序控制是否停留在任务线程中?我不知道你的确切意思,但如果你只调用Task.Run(...)
,你就不知道查询是否能在主线程上成功运行。
对我来说,我只会使用Task.Run(...)
,我总是需要知道查询的结果,所以我会使用Task.Run(…(.Await((,或者如果我不想阻塞主线程,我会结合回调来处理查询结果,如下所示:
Task.Run(()=>{
try {
//Run a long running DB update query
callback.onQueryRunSuccess();
}
catch(Exception e) {
callback.onQueryRunFailed(e);
}
});