等待异步任务结束

Sep*_*tos 1 c# asynchronous task

我有一个异步运行的任务,然后我有第二种方法,它需要从异步任务中检索信息。我无法修改异步任务,所以我想知道是否可以告诉第二种方法等待异步方法完成。

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();
Run Code Online (Sandbox Code Playgroud)

attribuerPlanning方法是异步方法,我希望在不修改方法本身的情况下,它在调用UpdateListeContrats.

或者说UpdateListeContrats,在另一种方法完成之前不要触发自己。

(目前,updateListeContrats在没有attributerPlanning方法更新信息的情况下启动。)

Mar*_*ell 5

首先,您实际上永远不应该“等待”(同步)任务,但可以“等待”它(异步)。

在这种情况下,最合适的地方可能是:在呼叫站点,即

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( ... );
}
Run Code Online (Sandbox Code Playgroud)

除了简单之外,这也避免了并发问题;大多数代码都没有预料到在同一上下文中的并发使用。

在一般情况下,您可以在一个地方捕获任务(等),然后等待它,但在您的情况下,问题变成了如何处理foreach/if等;如果您同时运行这些任务,则可能有零个、一个或多个此类任务。但我想你可以把它们放在一个列表中,即

var pending = new List<Task<int>>();
// ...
            pending.Add(attribuerPlanning);
// ...
var results = await Task.WhenAll(pending);
Run Code Online (Sandbox Code Playgroud)

  • @EmilianoJavierGonzález 访问 `.Result` 并不是一个好主意;这就是“同步优于异步”,它可能是**有害的**(它本质上与`.Wait()`相同) (3认同)