2011-03-23 14 views

Respuesta

7

La llamada a BeginGetResponse devuelve IAsyncResult. Mantenga una referencia a eso. Puede usar el IAsyncResult.AsyncState para verificar el estado de la solicitud.

Para cancelar la solicitud, llame al WebRequest.Abort de la instancia de WebRequest original.

Para realizar algo cuando se completen o cancelen todas las solicitudes, obtenga un WaitHandle del IAsyncResult.AsyncWaitHandle para cada una de sus solicitudes, luego espere todas. Código de muestra here.

+0

Gracias, eso es exactamente lo que estaba buscando. – PiZzL3

0

Será mejor que implemente Event Based Asynchronous Pattern para su desarrollo para detectar eventos en todas las etapas.

Básicamente, cómo sería crear primero una interfaz IAsyncCommand de la siguiente manera.

public interface IAsyncCommand<TRequest, TResponse, TCorrelation> : ICommand<TRequest, TResponse> 
{ 
    event CommandProgressChangedEventHandler<string, TCorrelation> ProgressChanged; 
    event CommandCompletedEventHandler<TResponse, TCorrelation> Completed; 

    bool CancellationPending { get; } 
    bool IsBusy { get; } 

    TCorrelation CorrelationId(TRequest request); 
    void ExecuteAsync(TRequest request); 
    void ExecuteAsync(TRequest request, CommandCompletedEventHandler<TResponse, TCorrelation> completedCallback, CommandProgressChangedEventHandler<string, TCorrelation> progressCallback); 
    void CancelAsync(); 
} 

poner en práctica esos dos CommandProgressChangedEventHander y la CommandCompletedEventHandler basado en su escenario y poblar el argumento en consecuencia.

Si asumimos que nuestro hilo debe comprobar si una determinada URL en cuestión es una URL válida, el código es el siguiente ....

public class UrlCheckCommand : AsyncCommandBase<string, bool, string>, IUrlCheckCommand 
{ 
    public override string CorrelationId(string request) 
    { 
     return request; //Guid.NewGuid().ToString(); 
    } 

    public override bool Execute(string request) 
    { 
     return CommandHelper.CheckUrlValidity(request); 
    } 
} 

La clase AsyncCommandBase es una clase abstracta que implementa la interfaz IAsyncCommand . El esqueleto de esta clase se define a continuación.

public abstract class AsyncCommandBase<TRequest, TResponse, TCorrelation> : IAsyncCommand<TRequest, TResponse, TCorrelation> 
{ 
    protected AsyncOperation operation = null; 
    protected BackgroundWorker worker = null; 

    #region IAsyncCommand<TRequest,TResponse,TCorrelation> Members 

     //Implement all the interface members as per your use.... 

    #endregion 

    protected void worker_DoWork(object sender, DoWorkEventArgs e) 
    { 
     e.Result = Execute((TRequest)e.Argument); 
    } 
    protected void worker_ProgressChanged(object sender, ProgressChangedEventArgs e) 
    { 
     OnProgressChanged(e); 
    } 
    protected void worker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e) 
    { 
     OnCompleted(e); 
    } 

    protected void ReportProgress(int percentageProgress, string message) 
    { 
     if (worker != null && worker.WorkerReportsProgress) 
      worker.ReportProgress(percentageProgress, message); 
     else 
      OnProgressChanged(new ProgressChangedEventArgs(percentageProgress, message)); 
    } 
    protected void OnProgressChanged(ProgressChangedEventArgs e) 
    { 
     if (ProgressChanged != null) 
     { 
      SendOrPostCallback callback = new SendOrPostCallback(delegate { ProgressChanged(this, new CommandProgressChangedEventArgs<string, TCorrelation>(e.ProgressPercentage, e.UserState as string, (TCorrelation)operation.UserSuppliedState)); }); 
      operation.Post(callback, null); 
     } 
    } 
    protected void OnCompleted(RunWorkerCompletedEventArgs e) 
    { 
     if (Completed != null) 
     { 
      TResponse response = default(TResponse); 
      if (e.Error == null) 
       response = (TResponse)e.Result; 

      SendOrPostCallback callback = new SendOrPostCallback(delegate { Completed(this, new CommandCompletedEventArgs<TResponse, TCorrelation>(response, e.Error, (TCorrelation)operation.UserSuppliedState, e.Cancelled)); }); 
      operation.PostOperationCompleted(callback, null); 
     } 
    } 
} 

Puede completar el controlador de progreso y evento finalizado y la clave es la población de argumento. Incluso puede usarlo para completar el progreso porcentual, estado de usuario, etc. ...

+0

no está compilando una API asíncrona desde cero, está usando una existente que no mencionas. http://msdn.microsoft.com/en-us/library/system.net.httpwebrequest.begingetresponse.aspx –

+0

@Robert: me he hecho las mismas preguntas (y de manera más destacada, capturé eventos completados o cancelados) y usé el evento. Patrón asincrónico basado para resolverlo de una mejor manera. Si puedes usar la API de subprocesamiento para crear tu propia API, eso resuelve el problema en todos los sentidos. He pegado esa línea de códigos de mi propia aplicación actualmente en vivo. URLCheck es solo un sustituto de GetWebRequest. Por favor revisa el código cuidadosamente. – DotNetInfo

Cuestiones relacionadas