81 votes

Comment faire en sorte qu'une méthode asynchrone retourne une valeur?

Je sais comment faire des méthodes Async, mais dis que j'ai une méthode qui fait beaucoup de travail, puis renvoie une valeur booléenne?

Comment puis-je renvoyer la valeur booléenne sur le rappel?

Clarification :

 public bool Foo(){
    Thread.Sleep(100000); // Do work
    return true;
}
 

Je veux être capable de rendre cela asynchrone.

154voto

Dave Arkell Points 1621

Si vous utilisez C # 5.0 , vous spécifiez alors la méthode

 public async Task<bool> doAsyncOperation()
{
    // do work
    return true;
}

bool result = await doAsyncOperation();
 

60voto

Marc Gravell Points 482669

Il y a plusieurs façons de faire cela ... la plus simple consiste à faire en sorte que la méthode asynchrone effectue également l'opération suivante. Une autre approche populaire consiste à transmettre un rappel, c'est-à-dire

 void RunFooAsync(..., Action<bool> callback) {
     // do some stuff
     bool result = ...

     if(callback != null) callback(result);
}
 

Une autre approche consiste à déclencher un événement (avec le résultat dans les données event-args) lorsque l'opération asynchrone est terminée.

De plus, si vous utilisez la bibliothèque TPL, vous pouvez utiliser ContinueWith :

 Task<bool> outerTask = ...;
outerTask.ContinueWith(task =>
{
    bool result = task.Result;
    // do something with that
});
 

4voto

Jim Mischel Points 68586

La manière la plus simple de le faire est probablement de créer un délégué, puis BeginInvoke , suivi d’une attente à l’avenir et d’un EndInvoke .

 public bool Foo(){
    Thread.Sleep(100000); // Do work
    return true;
}

public SomeMethod()
{
    var fooCaller = new Func<bool>(Foo);
    // Call the method asynchronously
    var asyncResult = fooCaller.BeginInvoke(null, null);

    // Potentially do other work while the asynchronous method is executing.

    // Finally, wait for result
    asyncResult.AsyncWaitHandle.WaitOne();
    bool fooResult = fooCaller.EndInvoke(asyncResult);

    Console.WriteLine("Foo returned {0}", fooResult);
}
 

3voto

NerdFury Points 9935

Utilisez un BackgroundWorker. Cela vous permettra d’obtenir des rappels à la fin et de suivre vos progrès. Vous pouvez définir la valeur Result sur les arguments de l'événement avec la valeur résultante.

     public void UseBackgroundWorker()
    {
        var worker = new BackgroundWorker();
        worker.DoWork += DoWork;
        worker.RunWorkerCompleted += WorkDone;
        worker.RunWorkerAsync("input");
    }

    public void DoWork(object sender, DoWorkEventArgs e)
    {
        e.Result = e.Argument.Equals("input");
        Thread.Sleep(1000);
    }

    public void WorkDone(object sender, RunWorkerCompletedEventArgs e)
    {
        var result = (bool) e.Result;
    }
 

-3voto

the_drow Points 6141

Vous devez utiliser la méthode EndXXX de votre méthode asynchrone pour renvoyer la valeur. EndXXX devrait attendre qu'il y ait un résultat en utilisant le WaitHandle de IAsyncResult et qu'un retour avec la valeur.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X