如果方法花费太长时间,则超时

时间:2014-02-28 00:10:33

标签: c# exception timeout sleep wait

我正在尝试超时并在等待指定的时间后抛出异常,并且想知道我目前的做法是否最好。

    class Timeout
    {

        XmlDocument doc;
        System.Object input;

        public Timeout(XmlDocument doc, System.Object input)
        {
            this.doc = doc;
            this.input = input;
        }

        public void run()
        {
            if (input is Stream)
            {
                doc.Load((Stream)input);
            }
            else if (input is XmlReader)
            {
                doc.Load((XmlReader)input);
            }
            else if (input is TextReader)
            {
                doc.Load((TextReader)input);
            }
            else
            {
                doc.Load((string)input);
            }
            System.Threading.Thread.CurrentThread.Abort();
        }

    }

    private void LoadXmlDoc(XmlDocument doc, System.Object input)
    {

        Timeout timeout = new Timeout(doc, input);
        System.Threading.Thread timeoutThread = new System.Threading.Thread(new ThreadStart(timeout.run));
        timeoutThread.Start();
        System.Threading.Thread.Sleep(this.timeout * 1000);
        if (timeoutThread.IsAlive)
        {
            throw new DataSourceException("timeout reached", timeout.GetHashCode());
        }
    }

这种当前的方法确实有效,所以我只是想知道是否有更简单/更好的方法来完成同样的事情。

3 个答案:

答案 0 :(得分:1)

除了我的评论(here's the link from it)之外,这里有关于线程的some more information。基本上,它归结为学习不同的设计/库,它们的优点和缺点,哪一个最适合您的需求。

根据我的理解,希望有更多关于这个主题的知识的人会参与其中,基本上有2个不同的类别,你可以把线程设计,同步和异步。您已使用异步设计,使用线程池。如果您想坚持使用此设计,可以尝试使用Task或同步操作Parallel

旁注:我不确定使用异常来处理简单逻辑的智慧。换句话说,exception可以简单地替换为返回boolean

答案 1 :(得分:1)

我最终做了什么:

    class Timeout
    {
        XmlDocument doc;
        System.Object input;

        public Timeout(XmlDocument doc, System.Object input)
        {
            this.doc = doc;
            this.input = input;
        }

        public void run()
        {
            if (input is Stream)
            {
                doc.Load((Stream)input);
            }
            else if (input is XmlReader)
            {
                doc.Load((XmlReader)input);
            }
            else if (input is TextReader)
            {
                doc.Load((TextReader)input);
            }
            else
            {
                doc.Load((string)input);
            }
        }
    }

    private void LoadXmlDoc(XmlDocument doc, System.Object input)
    {
        Timeout timeout = new Timeout(doc, input);
        System.Threading.Thread timeoutThread = new System.Threading.Thread(new ThreadStart(timeout.run));
        timeoutThread.Name = "XmlWorker" + threadNumber++;
        timeoutThread.Start(); 
        if (!timeoutThread.Join(this.timeout)) //Join returning false implies the timeout was reached
        {
            if (timeoutThread.IsAlive)
                timeoutThread.Abort();
            throw new DataConnectionException("timeout reached: " + this.timeout.Milliseconds + "ms", new TimeoutException(this.timeout.Milliseconds));
        }
    }

答案 2 :(得分:0)

尝试做这样的事情:

try
{
    var cts = new System.Threading.CancellationTokenSource();

    cts.CancelAfter(TimeSpan.FromSeconds(0.01));

    var tw = Task.Run<System.Xml.XmlDocument>(() =>
    {
        var doc = new System.Xml.XmlDocument();
        doc.Load("https://maps.googleapis.com/maps/api/geocode/xml?address=1+Exchange+Plaza+,+Floor+26+,+NY&sensor=false");
        return doc;
    }, cts.Token);

    var xml = await tw;
}
catch (TaskCanceledException e)
{

}