3

J'ai mis en IHttpAsyncHandler dans ma classe pour effectuer 5-6 processus long en arrière-plan et reconnaître au client le début de chaque tâche. Plus tôt, j'utilisais une variable de session et la mettais à jour avec l'état actuel de la tâche, et donnait une requête d'appel asynchrone au serveur de jquery dans l'intervalle de 5 secondes pour obtenir l'état actuel, mais cette implémentation n'est pas bonne. au serveur pour le statut.Comment envoyer la reconnaissance multiple client à l'aide IHttpAsyncHandler en asp.net

Puis j'ai implémenté IHttpAsyncHandler dans mon application, maintenant le serveur lui-même envoie un accusé de réception au client, mais selon mon implémentation je ne peux envoyer qu'un seul accusé de réception! si je tente d'envoyer plus d'un alors son erreur en donnant comme « référence d'objet pas encore défini à une instance d'un objet »

s'il vous plaît vérifier mon exemple de code.

dans mon code La méthode ExecuteFirst() fonctionne correctement en envoyant un accusé de réception au client mais ExecuteSecond() n'envoie pas d'accusé de réception à l'accusé de réception.

Je Goggled beaucoup, mais pas obtenir une bonne façon d'envoyer la reconnaissance multiple au client.

c'est mon exemple de code, s'il vous plaît aidez-moi si quelqu'un a une idée.

Javascript

function postRequest(url) { 

     var url = 'StartLongRunningProcess.ashx?JOBCODE=18' 

     var xmlhttp = getRequestObject(); 

     xmlhttp.open("POST", url, true); 


     xmlhttp.onreadystatechange = 
        function() { 

         if (xmlhttp.readyState == 4) { 
          var response = xmlhttp.responseText; 
          divResponse.innerHTML += "<p>" + response + "</p>";        
         } 
        } 


     xmlhttp.send(); 

    } 



function getRequestObject() { 
     var req; 

     if (window.XMLHttpRequest && !(window.ActiveXObject)) { 
      try { 
       req = new XMLHttpRequest(); 
      } 
      catch (e) { 
       req = false; 
      } 
     } 
     else if (window.ActiveXObject) { 
      try { 
       req = new ActiveXObject('Msxml2.XMLHTTP'); 
      } 
      catch (e) { 
       try { 
        req = new ActiveXObject('Microsoft.XMLHTTP'); 
       } 
       catch (e) { 
        req = false; 
       } 
      } 
     } 

     return req; 
    } 

StartLongRunningProcess.ashx.cs

public class StartLongRunningProcess: IHttpAsyncHandler, IRequiresSessionState 
{ 

      private AsyncRequestResult _asyncResult; 
    public void ProcessRequest(HttpContext context) {} 

    public bool IsReusable 
    { 
     get { return true;} 
    } 


    public IAsyncResult BeginProcessRequest(HttpContext context, System.AsyncCallback cb, object extraData) 
    { 

     int32 jobCode= convert.ToInt32(context.Request["JOBCODE"]); 
     _asyncResult = new AsyncRequestResult(context, cb, jobCode); 

        if(jobCode==18) 
        { 

        StartProcess18() 

        } 
        else 
        { 

        //StartProcessOther() 

        } 
} 



      private StartProcess18() 
      { 

       var task1= new Task(() => 
       { 
        ExecuteFirst();       
       }); 


       var task2 = task1.ContinueWith((t1) => 
       { 
        ExecuteSecond(); 
       }, TaskContinuationOptions.OnlyOnRanToCompletion); 

       task1.Start(); 
      } 



    private ExecuteFirst() 
    { 

      //notify to client that this job has been started 
     _asyncResult.CurrentContext.Response.Write("First task has been started"); 
     _asyncResult.Notify(); 

     // Above line of code successfully send a acknowledgement to client 

     //Doing some long running process 
    } 


    private ExecuteSecond() 
    { 

      //notify to client that this job has been started 
     _asyncResult.CurrentContext.Response.Write("Second task has been started"); 

      // Above line of code giving error and if I skip it and call Notify() this also does not work. 

     _asyncResult.Notify(); 


     //Doing some long running process 
    } 

    public void EndProcessRequest(IAsyncResult result) 
{ 

} 


} 

AsyncRequestResult.cs

public class AsyncRequestResult : IAsyncResult 
{ 
    private HttpContext context; 
    private AsyncCallback callback;  

    private ManualResetEvent completeEvent = null; 
    private object data; 
    private object objLock = new object(); 
    private bool isComplete = false;   

    public AsyncRequestResult(HttpContext ctx, AsyncCallback cb, object d) 
    { 
     this.context = ctx; 
     this.callback = cb; 
     this.data = d; 
    } 

    public HttpContext Context 
    { 
     get { return this.context; } 
    } 

    public void Notify() 
    { 
     //isComplete = true; 


     lock(objLock) 
     { 
      if(completeEvent != null) 
      { 
       completeEvent.Set(); 
      } 
     } 


     if (callback != null) 
     { 
      callback(this); 
     } 
    } 


    public object AsyncState 
    { 
     get { return this.data; } 
    } 


    public bool CompletedSynchronously 
    { 
     get { return false; } 
    } 


    public WaitHandle AsyncWaitHandle 
    { 
     get 
     { 
      lock(objLock) 
      { 
       if (completeEvent == null) 
        completeEvent = new ManualResetEvent(false); 

       return completeEvent; 
      } 
     } 
    } 


    public bool IsCompleted 
    { 
     get { return this.isComplete; } 
    } 

} 

Répondre

1

HttpContext.Current n'est pas null uniquement si vous y accédez dans un thread qui gère les demandes entrantes.

Votre tâche de continuation en cours s'exécute probablement sur un thread ThreadPool sans que le HttpContext.Current ne passe à la suite, ce qui signifie qu'elle est nulle.

Essayez le réglage de votre TaskScheduler à TaskScheduler.FromCurrentSynchronizationContext() afin de l'exécuter dans le même contexte.

 private StartProcess18() 
     { 

      var task1= new Task(() => 
      { 
       ExecuteFirst();       
      }); 


      var task2 = task1.ContinueWith((t1) => 
      { 
       ExecuteSecond(); 
      }, TaskContinuationOptions.OnlyOnRanToCompletion, TaskScheduler.FromCurrentSynchronizationContext()); 

      task1.Start(); 
     } 
+0

cela ne fonctionne pas, quand j'ajoute "TaskScheduler.FromCurrentSynchronizationContext()" dans mon code, il donne une erreur. –

+0

Montrez-moi l'erreur –

+1

Oui, je vais vous envoyer demain, une fois que j'atteins –

Questions connexes