【问题标题】:C# How to stop a method if it takes longer than 2 seconds?如果方法花费超过 2 秒,C# 如何停止方法?
【发布时间】:2012-04-27 16:18:25
【问题描述】:

以下程序将连接到网络并获取“msnbc.com”网页的html内容并打印出结果。如果从网页获取数据的时间超过 2 秒,我希望我的方法停止工作并返回。你能告诉我如何用一个例子来做到这一点吗?

public partial class Form1 : Form
{
    public Form1()
    {
        InitializeComponent();
    }

    private void button1_Click(object sender, EventArgs e)
    {
        gethtml();
        MessageBox.Show("End of program");
    }

    public void gethtml()
    {
        HttpWebRequest WebRequestObject = (HttpWebRequest)HttpWebRequest.Create("http://msnbc.com/");

        WebResponse Response = WebRequestObject.GetResponse();
        Stream WebStream = Response.GetResponseStream();

        StreamReader Reader = new StreamReader(WebStream);
        string webcontent = Reader.ReadToEnd();
        MessageBox.Show(webcontent);
    }
}

【问题讨论】:

  • 你可能想在一个线程中执行获取,如果超过两秒就中止线程(通过计时器设置/调用)。
  • @ashes999:这是一个非常非常糟糕的主意。 只有在您打算取消整个进程时才中止线程。 中止线程应该是最后的手段。中止托管线程可能会任意破坏数据结构。
  • 非常感谢您的所有回答。
  • @EricLippert 我们在 Silverlight 中的做法是创建一个可取消的 BackgroundWorker,它是可中止的。也许我应该更精确:)
  • @ashes999:安全中止不是线程的属性;它是线程正在做什么的属性。 线程是否会改变共享数据结构并在线程中止时使其处于无效状态?是相关问题。

标签: c# timer


【解决方案1】:

两秒太长了无法阻止用户界面。如果您计划在 50 毫秒或更短的时间内获得结果,您应该只阻止 UI。

阅读这篇文章,了解如何在不阻塞 UI 的情况下执行 Web 请求:

http://www.developerfusion.com/code/4654/asynchronous-httpwebrequest/

请注意,在 C# 5 中,这一切都会变得容易得多,目前它是 beta 版本。在 C# 5 中,您可以简单地使用 await 运算符来异步等待任务的结果。如果您想了解此类事情在 C# 5 中如何工作,请参阅:

http://msdn.microsoft.com/en-us/async

【讨论】:

    【解决方案2】:

    设置WebRequest 对象的Timeout 属性。 Documentation

    MSDN 示例:

    // Create a new WebRequest Object to the mentioned URL.
    WebRequest myWebRequest=WebRequest.Create("http://www.contoso.com");
    Console.WriteLine("\nThe Timeout time of the request before setting is : {0} milliseconds",myWebRequest.Timeout);
    
    // Set the 'Timeout' property in Milliseconds.
    myWebRequest.Timeout=10000;
    
    // This request will throw a WebException if it reaches the timeout limit before it is able to fetch the resource.
    WebResponse myWebResponse=myWebRequest.GetResponse();
    

    【讨论】:

      【解决方案3】:

      如上所述。超时

          public void gethtml()
          {
              HttpWebRequest WebRequestObject = (HttpWebRequest)HttpWebRequest.Create("http://msnbc.com/");
              WebRequestObject.Timeout = (System.Int32)TimeSpan.FromSeconds(2).TotalMilliseconds;
              try
              {
                  WebResponse Response = WebRequestObject.GetResponse();
                  Stream WebStream = Response.GetResponseStream();
      
                  StreamReader Reader = new StreamReader(WebStream);
                  string webcontent = Reader.ReadToEnd();
                  MessageBox.Show(webcontent);
              }
              catch (System.Net.WebException E)
              {
                  MessageBox.Show("Fail");
              }
          }
      

      【讨论】:

        【解决方案4】:

        您可以在 HttpWebRequest 上使用 TimeOut 属性

        【讨论】:

          【解决方案5】:

          考虑切换到内容的异步下载。您将停止阻塞 UI 线程,并且能够轻松处理多个请求。您可以在不影响 UI 的情况下显着增加超时时间,并且可以在收到响应后决定是否仍要获取数据。

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 2014-01-05
            • 1970-01-01
            • 2023-03-18
            • 2019-05-14
            • 1970-01-01
            • 2023-03-22
            • 2020-10-20
            • 2021-08-09
            相关资源
            最近更新 更多