2014-04-01 47 views
3

我寫了一個方法,從方程中獲得ETag。服務器上的XML文件。我是否正確寫了中止任務,如果超時(GetResponseAsync()沒有CancellationToken),我沒有其他想法如何做Exception任務中取消GetResponseAsync()和異常

這裏是代碼:

public static async Task<string> GetETagAsync(Uri feedLink) 
    { 
     const int millisecondsTimeout = 2500; 
     WebRequest webRequest = WebRequest.Create(feedLink); 
     webRequest.Method = "HEAD"; 
     try 
     { 
      Task<WebResponse> webResponse = webRequest.GetResponseAsync(); 
      if (await Task.WhenAny(webResponse, Task.Delay(millisecondsTimeout)) == webResponse) 
      { 
       using (var result = webResponse.Result) 
       { 
        return result.Headers["ETag"]; 
       } 
      } 
      else 
      { 
       webRequest.Abort(); 
       return null; 
      } 
     } 
     catch (Exception) 
     { 
      return null; 
     } 
    } 

編輯

我已經做了一些改動。從這個主題重寫異常和使用類:GetResponseAsync does not accept cancellationToken

代碼:

public static async Task<string> GetETagAsync(Uri feedLink) 
    { 
     const int millisecondsTimeout = 2500; 
     var cancellationTokenSource = new CancellationTokenSource(); 
     WebRequest webRequest = WebRequest.Create(feedLink); 
     webRequest.Method = "HEAD"; 

     try 
     { 
      Task<WebResponse> webResponse = WebRequestExtensions.GetResponseAsync(webRequest, cancellationTokenSource.Token); 
      if (await Task.WhenAny(webResponse, Task.Delay(millisecondsTimeout)) == webResponse) 
      { 
       using (var result = webResponse.Result) 
       { 
        return result.Headers["ETag"]; 
       } 
      } 
      else 
      { 
       cancellationTokenSource.Cancel(); 
       return null; 
      } 
     } 
     catch (AggregateException ex) 
     { 
      if (ex.InnerException is WebException) 
       return null; 

      throw; 
     } 
    } 

public static class WebRequestExtensions 
{ 
    public static async Task<WebResponse> GetResponseAsync(this WebRequest request, CancellationToken cancellationToken) 
    { 
     using (cancellationToken.Register(() => request.Abort(), useSynchronizationContext: false)) 
     { 
      try 
      { 
       var response = await request.GetResponseAsync(); 
       cancellationToken.ThrowIfCancellationRequested(); 
       return (WebResponse)response; 
      } 
      catch (WebException ex) 
      { 
       if (ex.Status == WebExceptionStatus.RequestCanceled) 
       { 
        cancellationToken.ThrowIfCancellationRequested(); 
       } 

       if (cancellationToken.IsCancellationRequested) 
       { 
        throw new TaskCanceledException(ex.Message, ex); 
       } 

       throw; 
      } 
     } 
    } 
} 

是不是正確的呢?

+2

你幾乎肯定不想捕獲所有異常並返回null。如果你不能處理這個異常,就讓它傳播出去。 – Servy

+0

可能重複的[GetResponseAsync不接受cancellationToken](http://stackoverflow.com/questions/19211972/getresponseasync-does-not-accept-cancellationtoken) – Noseratio

+0

@Noseratio我讀了這個,但我使用'webRequest.Abort() '而不是你的方法,我想知道它是否正確 –

回答

1

由於該方法本身不支持任何停止任務的方法,因此無法停止。你沒有辦法阻止它繼續做它計劃做的事情。 可以做的是確保這個異步方法的任務不會等待它完成。雖然你可以像你一樣返回一個值,但這似乎代表了一種特殊情況;您應該拋出一個異常來表明操作超時。

3

可以使用WebRequestExtensions類我寫到這裏來解決問題: https://github.com/openstacknetsdk/openstack.net/blob/master/src/corelib/Core/WebRequestExtensions.cs

該類完全支持一個CancellationTokenWebRequest.Timeout財產。

+0

我讀過:但不知道是否正確[取消異步webrequest?](http://stackoverflow.com/questions/8635723/cancel-an-async-webrequest) –

+0

@ J.Marciniak我不知道如何這與我的答案有關? –

+0

對不起,我的錯誤,這是遲到,我有閱讀困難。 –