繁体   English   中英

C#超时所有httpwebrequests

[英]c# TimeOut all 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)

明确地超时事件不是一个好方法。 您可能要在一段时间后查看“ 取消异步任务”

如果不想等待操作完成,则可以在一段时间后使用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方法终止线程。

编辑: 取消任务 - 更好的解释(

Task类提供了一种基于CancellationTokenSource类取消已启动任务的方法。

取消任务的步骤:

  1. 异步方法应除类型为CancellationToken的参数外

  2. 创建一个CancellationTokenSource类的实例,例如: var cts = new CancellationTokenSource();

  3. 将CancellationToken从实例传递给异步方法,例如: 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. 从我们为Task所渴望的地方捕获OperationCanceledException

  6. 我们可以通过调用CancellationTokenSource实例的Cancel方法CancellationTokenSource OperationCanceledException ,长时间运行的操作将抛出OperationCanceledException 我们还可以设置时间来取消该操作。

更多详细信息-MSDN链接

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM