2015-06-01 29 views
0

這不是關於如何中止線程pointhunters的問題。C#超時所有httpwebrequests

我正在製作一個multi-threaded程序,它在每個運行線程中都有一個httpwebrequest,我想如果我想阻止他們所有的中途通過,我必須計時。 有沒有辦法在多線程的基礎上做到這一點? 每個線程看起來是這樣的:

 HttpWebRequest webRequest = (HttpWebRequest)WebRequest.Create(url); 
     webRequest.Method = "GET"; 
     webRequest.Accept = "text/html"; 
     webRequest.AllowAutoRedirect = false; 
     webRequest.Timeout = 1000 * 10; 
     webRequest.ServicePoint.Expect100Continue = false; 
     webRequest.ServicePoint.ConnectionLimit = 100; 
     webRequest.UserAgent = "Mozilla/5.0 (Windows NT 6.3; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/42.0.2311.152 Safari/537.36"; 
     webRequest.Proxy = null; 
     WebResponse resp; 
     string htmlCode = null; 

     try 
     { 
      resp = webRequest.GetResponse(); 
      StreamReader sr = new StreamReader(resp.GetResponseStream(), System.Text.Encoding.UTF8); 
      htmlCode = sr.ReadToEnd(); 
      sr.Close(); 
      resp.Close(); 
     } 
    catch (Exception) 
+3

請格式化您的代碼。 –

+0

什麼不是格式化的? –

+1

這是您的代碼在您的IDE中的外觀? –

回答

0

計時超時事件明確是不是一個好方法。你可能想看看 Cancel Async Tasks after a Period of Time

您可以通過 使用CancellationTokenSource.CancelAfter方法取消一段時間後異步操作,如果你不想做 等待操作完成。此方法調度 取消未在 一段時間年代由CancelAfter表達指定內完成任何相關的任務。從MSDN

樣品的編號:

// Declare a System.Threading.CancellationTokenSource. 
     CancellationTokenSource cts; 

     private async void startButton_Click(object sender, RoutedEventArgs e) 
     { 
      // Instantiate the CancellationTokenSource. 
      cts = new CancellationTokenSource();  
      resultsTextBox.Clear();  
      try 
      { 
       // ***Set up the CancellationTokenSource to cancel after 2.5 seconds. (You 
       // can adjust the time.) 
       cts.CancelAfter(2500);  
       await AccessTheWebAsync(cts.Token); 
       resultsTextBox.Text += "\r\nDownloads succeeded.\r\n"; 
      } 
      catch (OperationCanceledException) 
      { 
       resultsTextBox.Text += "\r\nDownloads canceled.\r\n"; 
      } 
      catch (Exception) 
      { 
       resultsTextBox.Text += "\r\nDownloads failed.\r\n"; 
      }  
      cts = null; 
     }  

     // You can still include a Cancel button if you want to. 
     private void cancelButton_Click(object sender, RoutedEventArgs e) 
     { 
      if (cts != null) 
      { 
       cts.Cancel(); 
      } 
     }  

     async Task AccessTheWebAsync(CancellationToken ct) 
     { 
      // Declare an HttpClient object. 
      HttpClient client = new HttpClient();  
      // Make a list of web addresses. 
      List<string> urlList = SetUpURLList();  
      foreach (var url in urlList) 
      { 
       // GetAsync returns a Task<HttpResponseMessage>. 
       // Argument ct carries the message if the Cancel button is chosen. 
       // Note that the Cancel button cancels all remaining downloads. 
       HttpResponseMessage response = await client.GetAsync(url, ct);  
       // Retrieve the website contents from the HttpResponseMessage. 
       byte[] urlContents = await response.Content.ReadAsByteArrayAsync();  
       resultsTextBox.Text += 
        String.Format("\r\nLength of the downloaded string: {0}.\r\n" 
        , urlContents.Length); 
      } 
     } 

還有Thread.Abort Method終止該線程。

編輯:取消任務 - 一個更好的解釋(source

Task類提供了一種方法來取消基礎上,CancellationTokenSource類的啓動任務。

步驟來取消任務:

  1. 異步方法應該除外類型的參數CancellationToken

  2. 創建像CancellationTokenSource類的實例:var cts = new CancellationTokenSource();

  3. 從傳遞的CancellationToken所述instace到異步方法,如:Task<string> t1 = GreetingAsync("Bulbul", cts.Token);

  4. 從長時間運行的方法中,我們必須調用CancellationToken的ThrowIfCancellationRequested()方法。

      static string Greeting(string name, CancellationToken token) 
          { 
           Thread.Sleep(3000); 
           token. ThrowIfCancellationRequested(); 
           return string.Format("Hello, {0}", name); 
          } 
    
  5. 趕上OperationCanceledException從那裏我們awiting的任務。

  6. 我們可以通過調用CancellationTokenSource實例Cancel方法取消操作,OperationCanceledException將從長時間運行的操作被拋出。我們也可以設置時間來取消對instanc的操作。

更多詳細信息 - MSDN Link

static void Main(string[] args) 
    { 
     CallWithAsync(); 
     Console.ReadKey();   
    } 

    async static void CallWithAsync() 
    { 
     try 
     { 
      CancellationTokenSource source = new CancellationTokenSource(); 
      source.CancelAfter(TimeSpan.FromSeconds(1)); 
      var t1 = await GreetingAsync("Bulbul", source.Token); 
     } 
     catch (OperationCanceledException ex) 
     { 
      Console.WriteLine(ex.Message); 
     } 
    } 

    static Task<string> GreetingAsync(string name, CancellationToken token) 
    { 
     return Task.Run<string>(() => 
     { 
      return Greeting(name, token); 
     }); 
    } 

    static string Greeting(string name, CancellationToken token) 
    { 
     Thread.Sleep(3000); 
     token.ThrowIfCancellationRequested(); 
     return string.Format("Hello, {0}", name); 
    } 
+0

但我可以簡單地爲我的httpwebrequest設置一個超時。有沒有一種方法可以訪問我創建的對象?我有一個所有線程的線程表。 –

+0

您正在嘗試'超時'正在您的線程上執行的'HttpWebRequest'。我不認爲這是可能的,即使它是。這不是正確的方法。 –

+0

@tim_po - 請參閱編輯,我添加了對'CancellationToken'的使用說明 –