2

je pouvais vraiment faire avec un peu d'aide sur celui-ci - je suis complètement coincé :-(Brain Teaser: IAsyncResult AsyncState est nul après rappel dans ASP .Net Async page

J'ai mis en œuvre le modèle Async (correctement, je l'espère Dans un composant de recherche que j'ai développé, il est appelé à partir d'une page Async Asp. Net, en utilisant RegisterAsyncTask

Lorsque mon composant termine son travail, il appelle le rappel fourni, en passant un AsyncResult avec l'ensemble AsyncState à un Le débogueur confirme que la valeur n'est pas nulle lorsque le rappel est appelé

Lorsque l'AsyncResult arrive en tant que paramètre de la fonction de rappel sur le thread principal de la page - La propriété AsyncState est null.

Ce sont les sections pertinentes du composant de recherche:

public virtual IAsyncResult BeginSearchAsync(
     Object sender, 
     EventArgs e, 
     AsyncCallback cb, 
     object state) 
    { 
     _callback = cb; 

     //... Some code 

     // Start the asynchronous operation. 
     WorkerEventHandler workerDelegate = new WorkerEventHandler(SearchWorker); 
     return workerDelegate.BeginInvoke(
      paramz.terms, 
      paramz.sourceName, 
      asyncOp, 
      cb, 
      null); 
    } 

    protected void OnSearchCompleted(SearchCompleteEventArgs e) 
    { 
     if (_callback != null) 
     { 
      //SearchAsyncResult implements IAsyncResult    
      SearchAsyncResult result = new SearchAsyncResult(); 
      result.IsCompleted = true; 
      result.CompletedSynchronously = true; 
      result.AsyncState = "TEST"; 
      //result.AsyncState = e; 

      //at this point RESULT.ASYNCSTATE IS NEVER NULL!!! 
      _callback(result); 
     }    
    } 

Ceci est le code de la codebehind page d'appel (cette page a Async = true et un ensemble de valeur AsyncTimeout):

void searchSubmit_Click(object sender, EventArgs e) 
    { 

     foreach (RadPanelItem item in resultsPanelBar.GetAllItems()) 
     { 

      //... Some Code 
      SearchEngine engine = new SearchEngine(); 
      var task = new PageAsyncTask(engine.BeginSearchAsync, EndSearch, null,     srchParameters, true); 

      RegisterAsyncTask(task); 

     } 
    } 

    void EndSearch(IAsyncResult asyncResult) 
    { 

     if (asyncResult.AsyncState == null) 
      return; 
     //asyncResult.AsyncState: IS ALWAYS NULL!!! 

     SearchCompleteEventArgs result 
      = (SearchCompleteEventArgs)asyncResult.AsyncState; 

    } 
+0

Dans la méthode est rappelé à, dans ma page, le IAsyncResult qui est reçu est de type System.Runtime.Remoting.Messaging.AsyncResult. Par conséquent, la valeur de retour que je définis sur ma classe AsyncResult personnalisée n'est pas disponible ... – RobD

Répondre

2

La réponse courte est - je n'ai pas fait ma recherche à fond. Il y a de nombreux problèmes avec le code ci-dessus.

Le plus important (ce qui est maintenant évident pour moi), c'est que le IAsyncResultObject retourné par la méthode BeginSearchAsync, doit être conservé dans le composant. Cet objet est ensuite mis à jour par le composant lors de son fonctionnement. Ces modifications sont surveillées par le thread qui a démarré l'opération. Une fois que le composant a terminé son travail, il doit définir AsyncOperation comme terminé et stocker toute valeur de retour requise dans ce même objet.

L'implémentation de IAsyncResult est au-delà de trivial.

C'est l'article qui éclairci ma compréhension de ce qui se passait, et m'a donné une mise en œuvre concrète de partir pour obtenir une classe AsyncResult approprié pour mon scénario:

http://msdn.microsoft.com/en-us/magazine/cc163467.aspx

+0

+1 pour le lien. –