简体   繁体   English

等待异步任务结束

[英]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.

相关问题 如何在关闭进程之前等待任务结束? - How to wait a task to end before to close the processus? SQLite Asynchronous Task和Wait操作符 - 任务是否按正确顺序执行? - SQLite Asynchronous Task and the Wait operator - will Tasks execute in correct order? 关于异步任务,为什么要捕获OperationCanceledException需要Wait()? - Regarding asynchronous Task, why is a Wait() required to catch OperationCanceledException? 如何触发异步任务,但在返回 ActionResult 之前等待所有回调? - How to fire an asynchronous task, but wait for all callbacks before returning ActionResult? 如何等待任务执行结束以恢复程序执行 - How to wait for the end of the execution of a task to resume the execution of a program 在异步操作之后立即调用 Task.Wait() 是否等同于同步运行相同的操作? - Is calling Task.Wait() immediately after an asynchronous operation equivalent to running the same operation synchronously? 等待 Lua 中的异步事件 - Wait for Asynchronous Event in Lua 在ASP.NET请求结束之前,是否需要完成没有返回的异步任务 - Does an asynchronous task with no return need to finish before an ASP.NET request can end Task.Delay(0)不是异步的 - Task.Delay(0) not asynchronous 任务中的异步套接字操作 - Asynchronous socket operations in a Task
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM