web-dev-qa-db-fra.com

Comment faire pour que BackgroundWorker retourne un objet

Je dois faire RunWorkerAsync() retourner un List<FileInfo>. Comment puis-je renvoyer un objet d'un travailleur en arrière-plan?

53
Clair Vengs

Dans votre gestionnaire d'événements DoWork pour le BackgroundWorker (où se déroule le travail en arrière-plan), il y a un argument DoWorkEventArgs. Cet objet a un objet de propriété publique Result. Lorsque votre travailleur a généré son résultat (dans votre cas, un List<FileInfo>), ensemble e.Result à cela, et revenez.

Maintenant que votre BackgroundWorker a terminé sa tâche, il déclenche l'événement RunWorkerCompleted, qui a un objet RunWorkerCompletedEventArgs comme argument. RunWorkerCompletedEventArgs.Result contiendra le résultat de votre BackgroundWorker.

exemple:

private void bgw_DoWork(object sender, DoWorkEventArgs e)
{
    int result = 2+2;
    e.Result = result;
}

private void bgw_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
    int result = (int)e.Result;
    MessageBox.Show("Result received: " + result.ToString());
}
91
David

Je suppose que vous ne voulez pas bloquer et attendre RunWorkerAsync () pour les résultats (si vous le faisiez, il n'y aurait aucune raison d'exécuter async!

Si vous souhaitez être averti lorsque le processus d'arrière-plan se termine, connectez l'événement RunWorkerCompleted. Si vous souhaitez renvoyer un état, renvoyez-le dans le membre de résultat des arguments d'événement de DoWork.

EDIT: J'ai posté prématurément - terminé mon exemple de code

Exemple:



    private void BackgroundWorker_DoWork(object sender, DoWorkEventArgs e)
    {
      // do your thing
      ....
      // return results
      e.Result = theResultObject;
    }

    // now get your results
    private void BackgroundWorker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
    {
      MyResultObject result = (MyResultObject)e.Result;
      // process your result...
    }

20
JMarsch

RunWorkerAsync() démarre le processus de manière asynchrone et retournera et continuera d'exécuter votre code avant que le processus ne se termine réellement. Si vous voulez obtenir le résultat de BackgroundWorker, vous devrez créer une variable d'instance pour conserver cette valeur et la vérifier une fois que BackgroundWorker sera terminé.

Si vous voulez attendre la fin du travail, vous n'avez pas besoin d'un BackgroundWorker.

1
Adam Robinson

Vous pourriez avoir votre thread déclencher un événement avec l'objet comme argument:

ThreadFinishedEvent(this, new ThreadEventArgs(object));

où:

public class ThreadEventArgs : EventArgs
{
    public ThreadEventArgs(object object)
    {
        Object = object
    }

    public object Object
    {
        get; private set;
    }
}
1
ChrisF

Selon votre modèle, vous souhaitez soit que votre thread de travail soit rappelé à son créateur (ou à un autre processus) à la fin de son travail, soit vous devez interroger le thread de travail de temps en temps pour voir si c'est fait et, si alors, obtenez le résultat.

L'idée d'attendre qu'un thread de travail renvoie son résultat sape les avantages du multithreading.

0
Welbog

De manière générale lors de l'exécution d'un processus asynchrone, le thread de travail doit appeler un délégué ou déclencher un événement (comme ChrisF).

Vous pouvez consulter le nouveau PFX qui a une fonction de concurrence qui peut retourner des valeurs.

Par exemple, il existe une fonction appelée Parallel.ForEach () qui a une surcharge qui peut renvoyer une valeur.

consultez ceci pour plus d'informations

http://msdn.Microsoft.com/en-us/magazine/cc817396.aspx

0
Sruly