c#TimeOut所有httpwebrequests

时间:2015-06-01 14:33:15

标签: c# multithreading httpwebrequest

这不是关于如何中止线程pointhunters的问题。

我正在制作一个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)

1 个答案:

答案 0 :(得分: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. 的参数
  3. 创建一个CancellationTokenSource类的实例,如:var cts = new CancellationTokenSource();

  4. 将CancellationToken从instace传递给异步方法,例如:Task<string> t1 = GreetingAsync("Bulbul", cts.Token);

  5. 从长时间运行的方法来看,我们必须调用CancellationToken的ThrowIfCancellationRequested()方法。

              static string Greeting(string name, CancellationToken token)
                {
                   Thread.Sleep(3000);
                   token. ThrowIfCancellationRequested();
                  return string.Format("Hello, {0}", name);
                }
    
  6. 抓住OperationCanceledException我们正在努力完成任务。

  7. 我们可以通过调用Cancel实例的CancellationTokenSource方法取消操作,OperationCanceledException将从长时间运行的操作中抛出。我们也可以设置时间取消对instanc的操作。

  8. 更多详情 - 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);
        }