Question

Sur le plan conceptuel, j’aimerais accomplir les tâches suivantes, mais j’ai eu du mal à comprendre comment le coder correctement en C #:


SomeMethod { // Member of AClass{}
    DoSomething;
    Start WorkerMethod() from BClass in another thread;
    DoSomethingElse;
}

Ensuite, lorsque WorkerMethod () est terminé, exécutez la procédure suivante:


void SomeOtherMethod()  // Also member of AClass{}
{ ... }

Quelqu'un peut-il s'il vous plaît donner un exemple de cela?

Était-ce utile?

La solution

La classe BackgroundWorker a été ajoutée à .NET 2.0 dans ce but précis.

En un mot, vous le faites:

BackgroundWorker worker = new BackgroundWorker();
worker.DoWork += delegate { myBClass.DoHardWork(); }
worker.RunWorkerCompleted += new RunWorkerCompletedEventHandler(SomeOtherMethod);
worker.RunWorkerAsync();

Vous pouvez également ajouter des éléments fantaisistes tels que l'annulation et le rapport d'avancement si vous le souhaitez:)

Autres conseils

Dans .Net 2, BackgroundWorker a été introduit. Il est donc très facile d’exécuter des opérations asynchrones:

BackgroundWorker bw = new BackgroundWorker { WorkerReportsProgress = true };

bw.DoWork += (sender, e) => 
   {
       //what happens here must not touch the form
       //as it's in a different thread
   };

bw.ProgressChanged += ( sender, e ) =>
   {
       //update progress bars here
   };

bw.RunWorkerCompleted += (sender, e) => 
   {
       //now you're back in the UI thread you can update the form
       //remember to dispose of bw now
   };

worker.RunWorkerAsync();

En .Net 1, vous devez utiliser des threads.

Vous devez utiliser AsyncCallBacks. Vous pouvez utiliser AsyncCallBacks pour spécifier un délégué à une méthode, puis spécifier des méthodes CallBack appelées une fois l'exécution de la méthode cible terminée.

Voici un petit exemple, lancez-le et voyez-le par vous-même.

programme de classe     {

    public delegate void AsyncMethodCaller();


    public static void WorkerMethod()
    {
        Console.WriteLine("I am the first method that is called.");
        Thread.Sleep(5000);
        Console.WriteLine("Exiting from WorkerMethod.");
    }

    public static void SomeOtherMethod(IAsyncResult result)
    {
        Console.WriteLine("I am called after the Worker Method completes.");
    }



    static void Main(string[] args)
    {
        AsyncMethodCaller asyncCaller = new AsyncMethodCaller(WorkerMethod);
        AsyncCallback callBack = new AsyncCallback(SomeOtherMethod);
        IAsyncResult result = asyncCaller.BeginInvoke(callBack, null);
        Console.WriteLine("Worker method has been called.");
        Console.WriteLine("Waiting for all invocations to complete.");
        Console.Read();

    }
}

Bien qu'il existe plusieurs possibilités ici, j'utiliserais un délégué appelé de manière asynchrone à l'aide de la méthode BeginInvoke .

Avertissement : n'oubliez pas d'appeler toujours EndInvoke sur le IAsyncResult pour éviter les fuites de mémoire éventuelles, comme décrit dans cet article .

Découvrez BackgroundWorker.

Utiliser des délégués asynchrones:

// Method that does the real work
public int SomeMethod(int someInput)
{
Thread.Sleep(20);
Console.WriteLine(”Processed input : {0}”,someInput);
return someInput+1;
} 


// Method that will be called after work is complete
public void EndSomeOtherMethod(IAsyncResult result)
{
SomeMethodDelegate myDelegate = result.AsyncState as SomeMethodDelegate;
// obtain the result
int resultVal = myDelegate.EndInvoke(result);
Console.WriteLine(”Returned output : {0}”,resultVal);
}

// Define a delegate
delegate int SomeMethodDelegate(int someInput);
SomeMethodDelegate someMethodDelegate = SomeMethod;

// Call the method that does the real work
// Give the method name that must be called once the work is completed.
someMethodDelegate.BeginInvoke(10, // Input parameter to SomeMethod()
EndSomeOtherMethod, // Callback Method
someMethodDelegate); // AsyncState

Ok, je ne sais pas comment vous voulez vous y prendre. D'après votre exemple, il semble que WorkerMethod ne crée pas son propre thread à exécuter, mais vous souhaitez appeler cette méthode sur un autre thread.

Dans ce cas, créez une méthode de travail abrégée qui appelle WorkerMethod, puis SomeOtherMethod, et mettez cette méthode en file d'attente sur un autre thread. Ensuite, lorsque WorkerMethod est terminé, SomeOtherMethod est appelé. Par exemple:

public class AClass
{
    public void SomeMethod()
    {
        DoSomething();

        ThreadPool.QueueUserWorkItem(delegate(object state)
        {
            BClass.WorkerMethod();
            SomeOtherMethod();
        });

        DoSomethingElse();
    }

    private void SomeOtherMethod()
    {
        // handle the fact that WorkerMethod has completed. 
        // Note that this is called on the Worker Thread, not
        // the main thread.
    }
}
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top