2009-12-27 3 views
2

J'essaie de comprendre comment cela fonctionne exactement.Comprendre Asynchronous HttpWebRequest

HttpWebRequest a une méthode BeginGetResponse qui accepte comme paramètre un ResponseCallback. Tout d'abord, est ce rappel appelé immédiatement (dans un nouveau thread) ou une fois qu'il reçoit une réponse du serveur? Ou est-ce le travail de EndGetResponse d'attendre la réponse? Deuxièmement, une fois que vous avez la réponse, vous pouvez accéder au flux de réponse immédiatement, mais le flux ne contient pas la page complète jusqu'à ce que le téléchargement soit terminé, d'où BeginRead. Cependant, je semble être en mesure d'accéder à tous les en-têtes immédiatement, à travers des propriétés comme HttpWebResponse.ContentLength. Cela signifie-t-il que EndGetResponse ne se termine pas tant que les en-têtes ne sont pas entièrement téléchargés ou est-ce que lorsque vous appelez le paramètre ContentLength, il se bloque pendant un certain temps jusqu'à ce que cet en-tête soit reçu?

Répondre

5

Begin * et le modèle Fin * est toujours le même:

  • passe dans un AsyncCallback à Begin
  • Attendez que l'appel de ce rappel (pas immédiate)
  • fin d'appel * toujours dans le rappel
  • Vérifiez le succès du rappel/IAsyncResult (était-ce annulé? les exceptions/erreurs?)
  • Utilisez le résultat de fin * ici ..

Le résultat dans votre cas est une instance de WebResponse, qui contient les en-têtes. Donc je pense qu'il est sûr de supposer que cette partie de la réponse a déjà été reçue: L'objet WebResponse n'a pas de magie async cachée dans ses propriétés. Si vous accédez à ContentLength, il s'agit simplement d'une propriété classique et l'objet ne sait pas ou ne s'en soucie pas si vous l'avez obtenu à l'aide d'un blocage ou d'un appel asynchrone.

+0

Vous pensez donc que le ResponseCallback n'est pas appelé tant que les en-têtes ne sont pas téléchargés? C'est suffisant. Savez-vous comment vérifier si elle a été annulée, ou est le seul moyen de vérifier l'exception lancée par 'EndGetResponse'? – mpen

+0

Sauf si vous implémentez un moyen d'annuler cette opération, je ne saurais pas comment cette méthode particulière pourrait être arrêtée - elle s'exécute comme une opération sur le ThreadPool et ni vous ni l'utilisateur ne pouvez l'arrêter maintenant. Le schéma général permet cependant un meilleur mécanisme d'annulation, en prolongeant le contrat. WebClient par exemple le fait et vous permet de vous abonner aux événements qui obtiennent une instance de AsyncCompletedEventArgs, qui à nouveau fournit une propriété .Cancelled. C'est de la commodité pure basée sur le modèle donné ci-dessus. –

+0

Il peut facilement être arrêté réellement: 'ThreadPool.RegisterWaitForSingleObject (asyncResult.AsyncWaitHandle, TimeoutCallback, conn, TimeOutInterval, true);' Je suppose que je pourrais ajouter ma propre propriété 'Cancelled' pendant que je suis à lui. 'WebClient' ne fait pas exactement ce que je veux, donc je le reconstruis pour être un peu plus flexible et supporter plusieurs téléchargements simultanés. – mpen