Quelle est l'utilisation d'AsyncCallback et pourquoi devrions-nous l'utiliser?
Lorsque la méthode async
termine le traitement, la méthode AsyncCallback
est automatiquement appelée, où les instructions de post-traitement peuvent être exécutées. Avec cette technique, il n'est pas nécessaire d'interroger ou d'attendre la fin du thread async
.
Voici quelques explications supplémentaires sur Async
Utilisation du rappel:
Modèle de rappel: Le modèle de rappel nécessite que nous spécifions une méthode de rappel et que nous incluions tout état dont nous avons besoin dans la méthode de rappel pour terminer l'appel. Le modèle de rappel peut être vu dans l'exemple suivant:
static byte[] buffer = new byte[100];
static void TestCallbackAPM()
{
string filename = System.IO.Path.Combine (System.Environment.CurrentDirectory, "mfc71.pdb");
FileStream strm = new FileStream(filename,
FileMode.Open, FileAccess.Read, FileShare.Read, 1024,
FileOptions.Asynchronous);
// Make the asynchronous call
IAsyncResult result = strm.BeginRead(buffer, 0, buffer.Length,
new AsyncCallback(CompleteRead), strm);
}
Dans ce modèle, nous créons un nouveau délégué AsyncCallback
, spécifiant une méthode à appeler (sur un autre thread) lorsque l'opération est terminée. De plus, nous spécifions un objet dont nous pourrions avoir besoin comme état de l'appel. Pour cet exemple, nous envoyons l'objet stream car nous devrons appeler EndRead
et fermer le flux.
La méthode que nous créons pour être appelée à la fin de l'appel ressemblerait à ceci:
static void CompleteRead(IAsyncResult result)
{
Console.WriteLine("Read Completed");
FileStream strm = (FileStream) result.AsyncState;
// Finished, so we can call EndRead and it will return without blocking
int numBytes = strm.EndRead(result);
// Don't forget to close the stream
strm.Close();
Console.WriteLine("Read {0} Bytes", numBytes);
Console.WriteLine(BitConverter.ToString(buffer));
}
Les autres techniques sont Wait-until-done et Polling.
modèle en attente Le modèle en attente vous permet de démarrer l'appel asynchrone et d'effectuer d'autres tâches. Une fois que l'autre travail est terminé, vous pouvez essayer de mettre fin à l'appel et il se bloquera jusqu'à ce que l'appel asynchrone soit terminé.
// Make the asynchronous call
strm.Read(buffer, 0, buffer.Length);
IAsyncResult result = strm.BeginRead(buffer, 0, buffer.Length, null, null);
// Do some work here while you wait
// Calling EndRead will block until the Async work is complete
int numBytes = strm.EndRead(result);
Ou vous pouvez utiliser des poignées d'attente.
result.AsyncWaitHandle.WaitOne();
Polling Model La méthode d'interrogation est similaire, à l'exception que le code interrogera le IAsyncResult
pour voir s'il s'est terminé.
// Make the asynchronous call
IAsyncResult result = strm.BeginRead(buffer, 0, buffer.Length, null, null);
// Poll testing to see if complete
while (!result.IsCompleted)
{
// Do more work here if the call isn't complete
Thread.Sleep(100);
}
Pense-y de cette façon. Vous avez certaines opérations que vous souhaitez exécuter en parallèle. Vous pouvez l'activer en utilisant des threads qui s'exécutent de manière asynchrone. Il s'agit d'un mécanisme d'incendie et d'oubli.
Mais certaines situations appellent un mécanisme où vous pouvez tirer et oublier mais avez besoin d'une notification lorsque l'opération est terminée. Pour cela, vous utiliseriez un rappel asynchrone.
L'opération est asynchrone mais vous rappelle à la fin de l'opération. L'avantage est que vous n'avez pas à attendre l'opération jusqu'à la fin. Vous êtes libre d'exécuter d'autres opérations et donc votre thread n'est pas bloqué.
Un exemple de ceci serait un transfert en arrière-plan d'un gros fichier. Pendant le transfert, vous ne voulez pas vraiment empêcher l'utilisateur de faire d'autres opérations. Une fois le transfert terminé, le processus vous rappellera sur une méthode asynchrone, où vous pourrez probablement faire apparaître une boîte de message indiquant "Transfert terminé"
Les AsyncCallbacks sont utilisés pour spécifier une fonction à appeler lorsqu'une opération asynchrone est terminée. Par exemple, si vous effectuez une opération IO, vous appelez BeginRead sur un flux et transmettez un délégué AsyncCAllback. La fonction est appelée lorsque l'opération de lecture est terminée.
Pour plus d'informations, voir: