2015-06-01 4 views
0

это не вопрос о том, как отменить поток pointhunters.C# TimeOut все 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, который завершает поток.

EDIT:Отмена задач - лучшее объяснение (source)

Класс Task обеспечивает способ отменить начатую задачу на основе класса CancellationTokenSource.

шаги, чтобы отменить задачу:

  1. асинхронный метод должен за исключением параметра типа CancellationToken

  2. Создать экземпляр класса CancellationTokenSource как: var cts = new CancellationTokenSource();

  3. Пропустите CancellationToken от к асинхронному методу, например: Task<string> t1 = GreetingAsync("Bulbul", cts.Token);

  4. Из метода длительной работы мы должны вызвать метод ThrowIfCancellationRequested() CancellationToken.

      static string Greeting(string name, CancellationToken token) 
          { 
           Thread.Sleep(3000); 
           token. ThrowIfCancellationRequested(); 
           return string.Format("Hello, {0}", name); 
          } 
    
  5. Поймать OperationCanceledException откуда мы awiting для выполнения этой задачи.

  6. Мы можем отменить операцию, позвонив по телефону Cancel. Например, метод CancellationTokenSource, 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. есть ли способ, которым я могу получить доступ к объекту im, создающему? У меня есть список нитей всех потоков. –

+0

Вы пытаетесь «Timeout» 'HttpWebRequest', который выполняется в вашем потоке. Я не думаю, что это возможно или даже если это так. Это неправильный путь. –

+0

@tim_po - см. Редактировать, я добавил объяснение использования 'CancellationToken' –