2011-03-23 6 views
5

मान लें कि मेरे पास 50 अनुरोध हैं जिन्हें मैंने BeginGetResponse का उपयोग शुरू किया।सी # कैसे "जांचें", "रद्द करें", और Async WebRequests पर प्रतीक्षा करें?

मैं प्रत्येक अनुरोध की स्थिति कैसे देखूं?
और मैं इसे कैसे रद्द करूं (कभी-कभी वे लटकते हैं)?
और जब सभी अनुरोध या तो पूर्ण या रद्द हो जाते हैं तो मैं एक कार्रवाई कैसे कर सकता हूं?

+0

पूर्ण स्रोत कोड के साथ कोई अंतिम समाधान? – Kiquenet

उत्तर

7

BeginGetResponse पर कॉल IAsyncResult देता है। इसका संदर्भ रखें। अनुरोध की स्थिति की जांच करने के लिए आप IAsyncResult.AsyncState का उपयोग कर सकते हैं।

अनुरोध रद्द करने के लिए, मूल WebRequest उदाहरण के WebRequest.Abort पर कॉल करें।

सभी अनुरोध पूरा होने या रद्द होने पर कुछ करने के लिए, अपने प्रत्येक अनुरोध के लिए IAsyncResult.AsyncWaitHandle से प्रतीक्षा करेंडल प्राप्त करें, फिर उन सभी पर प्रतीक्षा करें। नमूना कोड here

+0

धन्यवाद, यह वही है जो मैं ढूंढ रहा था। – PiZzL3

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

आप प्रगति और पूर्ण घटना हैंडलर को पॉप्युलेट कर सकते हैं और वे तर्क आबादी के लिए महत्वपूर्ण हैं। आप प्रगतिशीलता, उपयोगकर्तास्टेट आदि भरने के लिए भी इसका उपयोग कर सकते हैं ...

+0

वह स्क्रैच से एसिंक एपीआई नहीं बना रहा है, वह एक मौजूदा व्यक्ति का उपयोग कर रहा है जिसका आप कोई उल्लेख नहीं करते हैं। http://msdn.microsoft.com/en-us/library/system.net.httpwebrequest.begingetresponse.aspx –

+0

@Robert - मैंने खुद से एक ही प्रश्न पूछा है (और अधिक प्रमुख रूप से - अपूर्ण या रद्द घटनाओं को पकड़ना) और ईवेंट का उपयोग किया बेहतर तरीके से इसे हल करने के लिए आधारित असीमित पैटर्न। यदि आप अपने स्वयं के एपीआई के साथ आने के लिए थ्रेडिंग एपीआई का उपयोग कर सकते हैं, तो यह सभी तरह से समस्या हल करता है। मैंने अपने वर्तमान में लाइव एप्लिकेशन से कोड की उन पंक्तियों को चिपकाया है। URLCheck GetWebRequest के लिए सिर्फ एक विकल्प है। कोड को ध्यान से देखें। – DotNetInfo

संबंधित मुद्दे