2011-03-23 47 views

回答

7

BeginGetResponse调用返回的IAsyncResult。保留一个参考。您可以使用IAsyncResult.AsyncState来检查请求的状态。

要取消请求,调用原始WebRequest实例的WebRequest.Abort

要在所有的请求都完成或取消执行的东西,得到IAsyncResult.AsyncWaitHandle一个WaitHandle中为每个请求,然后等待他们的所有。示例代码here

+0

谢谢,这正是我正在寻找的。 – PiZzL3 2011-03-23 22:36:49

0

你会好起来的实施Event Based Asynchronous Pattern为您的发展赶上在所有不同阶段的活动。

基本上,我怎么会通过如下:首先创建一个IAsyncCommand接口去。

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(); 
} 

实现这两个CommandProgressChangedEventHander和CommandCompletedEventHandler根据您的情况,并相应地填充参数。

如果我们假设我们的线程应该检查有问题特定的URL是否是一个有效的URL,代码去如下....

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); 
    } 
} 

的AsyncCommandBase类是实现IAsyncCommand接口的抽象类。 这个类的骨架定义如下。

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); 
     } 
    } 
} 

可以填充进度和完成的事件处理程序,他们关键是争论的人口。你甚至可以用它来填充progresspercentage,userstate等等

+0

他并没有从头开始构建异步API,他使用了一个你没有提到的现有API。 http://msdn.microsoft.com/en-us/library/system.net.httpwebrequest.begingetresponse.aspx – 2011-03-23 04:35:54

+0

@Robert - 我问自己同样的问题(更突出 - 捕oncompleted或取消的事件)和使用的事件基于异步模式来更好地解决它。如果您可以使用线程API来创建您自己的API,那么这确实可以解决问题。我从我自己的当前实时应用程序粘贴了这些代码行。 URLCheck只是GetWebRequest的替代品。请仔细阅读代码。 – DotNetInfo 2011-03-23 05:11:51