[英]Wait for the end of an asynchronous task
I have a task that runs asynchronously, and I have a second method, right after that, that needs to retrieve the information from the asynchronous task.我有一个异步运行的任务,然后我有第二种方法,它需要从异步任务中检索信息。 I can't modify the asynchronous task, so I wanted to know if it's possible to tell the second method to wait until the asynchronous method is finished.我无法修改异步任务,所以我想知道是否可以告诉第二种方法等到异步方法完成。
foreach (AgentModel ag in Agents)
{
if (ag.IsEnabledRow == true)
{
if (ag.IsSelected == true)
{
if (ag.selectedMatrice != null)
{
if (ag.selectedWeeks != null)
{
//on vérifie le cycle choisi et on adapte la date en conséquence
semaineAAppliquer(ag);
ag.IsEnabledRow = false;
Task<int> attribuerPlanning = Gestion.AttrPlanning(
_dataService.ParamGlobaux.IDEtablissement,
_dataService.ParamGlobaux.Matricule,
_dataService.ParamGlobaux.ConnectionString,
ag.Matricule, ag.selectedMatrice.IDMatrice, DsCalendrierCongés,
dateDebutCycle, ag.dateFin, HoraireAZero, CompleterPriseVide,
RemplacerRH, JFRepos,
(text, title, buttons) => System.Windows.MessageBox.Show(
text, title, buttons), _progress, DecalageSemaine,
appliquerCouleur, _ToutEtablissement);
}
}
else
{
System.Windows.MessageBox.Show($"Sélectionner une matrice pour" +
$" l'agent {ag.Nom}.");
}
}
}
}
UpdateListeContrats();
The attribuerPlanning
method is the asynchronous method, and I would like, without modifying the method itself, that it ends before calling UpdateListeContrats
. attribuerPlanning
方法是异步方法,我希望在不修改方法本身的情况下,它在调用UpdateListeContrats
之前结束。
Or a way of saying UpdateListeContrats
, don't trigger yourself until the other method is complete.或者说UpdateListeContrats
的一种方式,在其他方法完成之前不要触发自己。
(Currently, updateListeContrats
launches without having the information updated by the attributerPlanning
method.) (目前, updateListeContrats
启动时没有通过attributerPlanning
方法更新信息。)
Firstly, you should virtually never "wait" (synchronous) for a task, but it is fine to "await" it (asynchronous).首先,您实际上不应该“等待”(同步)任务,但可以“等待”它(异步)。
In this case, the most appropriate place to do this is probably: at the call site, ie在这种情况下,最合适的地方可能是:在呼叫站点,即
if (ag.selectedWeeks != null)
{
//on vérifie le cycle choisi et on adapte la date en conséquence
semaineAAppliquer(ag);
ag.IsEnabledRow = false;
var result = await Gestion.AttrPlanning( ... );
}
In addition to being simple, this also avoids concurrency issues;除了简单之外,这也避免了并发问题; most code is not anticipating concurrent usage in the same context.大多数代码都没有预料到同一上下文中的并发使用。
In the general case, you can capture the task (etc) at one place, and await it later, but in your case the problem becomes what to do about the foreach
/ if
etc;在一般情况下,您可以在一个地方捕获任务(等),然后等待它,但在您的情况下,问题变成了如何处理foreach
/ if
等; there could be zero, one, or many such tasks, if you are running them concurrently.如果您同时运行它们,则可能有零个、一个或多个这样的任务。 But I guess you could throw them in a list, ie但我想你可以把它们放在一个列表中,即
var pending = new List<Task<int>>();
// ...
pending.Add(attribuerPlanning);
// ...
var results = await Task.WhenAll(pending);
UPDATE: As Marc pointed out, don't do this if you have something that shouldn't or mustn't be blocked in the main thread, like a GUI.更新:正如 Marc 指出的那样,如果您有一些不应该或不应该在主线程中阻塞的东西,比如 GUI,请不要这样做。
You can do attribuerPlanning.Wait();
你可以做attribuerPlanning.Wait();
after calling it.调用后。
Or if you want to run all task in the foreach async and wait all task to finish before UpdateListeContrats you can create a task list outside of the foreach:或者,如果您想在 foreach 异步中运行所有任务并等待所有任务在 UpdateListeContrats 之前完成,您可以在 foreach 之外创建一个任务列表:
List<Task> tasks = new List<Task>();
and in the loop body add the current task to the list:并在循环体中将当前任务添加到列表中:
var task = Task.Run(() => Gestion.AttrPlanning(...) );
tasks.Add(task);
and outside of foreach do在 foreach 之外做
Task.WhenAll(tasks).Wait();
UpdateListeContrats();
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.