线程停止,XMLexception错误

时间:2014-02-24 16:23:35

标签: c# multithreading threadpool

所以我启动一个线程计时器并且它可以正常工作,但线程计时器中的方法从yahoo API读取XML,有时对服务器的响应很糟糕,因此抛出XMLexception。但似乎这会阻止线程或其他东西,因为线程启动良好,但是当抛出异常时,所有线程都会停止。那么错了,我可以在每次停止另一个线程时启动一个线程吗?因为所有线程都停止,然后没有线程启动agiend。

try
        {
            System.Threading.Timer timer;
            timer = new System.Threading.Timer(new TimerCallback(TimerHelper), null, 0, 3000);
        }
        catch (Exception)
        {

        }

TimerHelper(object obj)尝试catch异常。

public void TimerHelper(object obj)
    {

        try
        {
            if (dataGridView.Rows.Count > 0 && !(dataGridView.Rows[0].Cells[0].Value == null)) // Updates the rows idividualy as long as first row is not empty
            {
                string[] cells;
                cells = new string[dataGridView.Columns.Count * dataGridView.Rows.Count];
                for (int i = 0; i < dataGridView.RowCount; i++)
                {
                    if (!(dataGridView.Rows[i].Cells[0].Value == null || dataGridView.Rows[i].Cells[0].Value.ToString() == "-")) // Makes sure that the row to update is not an empty row
                    {
                        String symbol;
                        symbol = Convert.ToString(dataGridView.Rows[i].Cells[0].Value);
                        String URLString2 = "http://query.yahooapis.com/v1/public/yql?q=select%20*%20from%20yahoo.finance.quotes%20where%20symbol%20in%20(%22" + symbol + "%22)%0A%09%09&diagnostics=true&env=http%3A%2F%2Fdatatables.org%2Falltables.env";
                        for (int t = 2; t < dataGridView.Columns.Count; t++)
                        {
                            dataGridView.SuspendLayout();
                            XmlTextReader reader2 = new XmlTextReader(URLString2); // Makes the reader read from the string abow ( URL )
                            string NasdaqOpenTime = "09:00:00";

                            // if the market haven't been open for the day then theres no DaysLow value
                            if (dataGridView.Columns[t].HeaderText == "DaysLow" && DateTime.Now.CompareTo(DateTime.Parse(NasdaqOpenTime)) == -1)
                            {
                                cells[t - 2] = "0";
                            }

                            // if the market haven't been open for the day then theres no DaysHigh value
                            if (dataGridView.Columns[t].HeaderText == "DaysHigh" && DateTime.Now.CompareTo(DateTime.Parse(NasdaqOpenTime)) == -1)
                            {
                                cells[t - 2] = "0";
                            }
                            else
                            {
                                reader2.ReadToFollowing(dataGridView.Columns[t].HeaderText);  // Reada until it fins the elemnt Bid , then stops on it
                                reader2.ReadStartElement(dataGridView.Columns[t].HeaderText); // Recognizes Bid as start element (Bid)
                                string temporary;
                                temporary = reader2.ReadString();
                                Trace.WriteLine(dataGridView.Columns[t].HeaderText + ": " + temporary);
                                cells[t - 2] = temporary; // Reads the text in between (Declared as a string) actualy the bid value
                                reader2.ReadEndElement();  // Checks that the current nod is an end element (/Bid) if so then continue
                                reader2.ResetState();
                            }

                        }

                    }
                }
                for (int h = 0; h < dataGridView.Rows.Count; h++)
                {
                    for (int t = 2; t < dataGridView.Columns.Count; t++)
                    {
                        dataGridView.Rows[h].Cells[t].Value = cells[t - 2];
                    }
                }
            }
        }
        catch (XmlException)
        {
        }
        catch (Exception)
        {

        }
    }

以下是在TimerHelper(对象obj)中跟踪值的示例输出。

    'FetchBySymbol.vshost.exe' (Managed (v4.0.30319)): Loaded 'C:\Users\Mattias\documents\visual studio 2012\Projects\FetchBySymbol\FetchBySymbol\bin\Debug\FetchBySymbol.exe', Symbols loaded.
    'FetchBySymbol.vshost.exe' (Managed (v4.0.30319)): Loaded 'C:\Windows\Microsoft.Net\assembly\GAC_MSIL\System.Configuration\v4.0_4.0.0.0__b03f5f7f11d50a3a\System.Configuration.dll'
    Ask: 37.44
    Bid: 37.43
...
...
...
    Ask: 37.44
    Bid: 37.43
    Ask: 37.42
    Bid: 37.41
    The thread '<No Name>' (0x104c) has exited with code 0 (0x0).
    The thread '<No Name>' (0x1920) has exited with code 0 (0x0).
    A first chance exception of type 'System.Net.WebException' occurred in System.dll
    A first chance exception of type 'System.Net.WebException' occurred in System.Xml.dll
    The thread '<No Name>' (0xe3c) has exited with code 0 (0x0).
    The thread '<No Name>' (0x1af0) has exited with code 0 (0x0).
    The thread '<No Name>' (0x1b18) has exited with code 0 (0x0).
    The thread '<No Name>' (0xb90) has exited with code 0 (0x0).
    The thread '<No Name>' (0x20) has exited with code 0 (0x0).

为什么退出?

2 个答案:

答案 0 :(得分:0)

请勿捕获通用Exception因为使用(发布的代码)

catch (Exception) { }

会导致每个可能的Exception通过你的手指滑落的情况。

尝试找出System.Net.WebException可能出现的位置并命名您的主题,以便您对正在发生的事情有更深入的了解,例如:

(new Thread(() => {}) { Name = "Some thread" }).Start();

输出

The thread 'Some thread' (0x260c) has exited with code 0 (0x0).

如果您想知道那些first chance exceptions是什么,请查看http://blogs.msdn.com/b/davidklinems/archive/2005/07/12/438061.aspx

正如@BlackICE所述,请发布缺失的代码,以便解决问题。

修改

您确定要找到合适的地方来解决这个问题。如上所述,线程退出不是问题的标志(你确实希望线程在完成工作时退出),也不是第一次机会异常(抛出但处理异常)。

这可能是CGd计时器问题吗,就像在这篇文章中一样?

System.Threading.Timer not firing after some time

修改

尝试这样的事,m'kay?它将以非阻塞的方式永远运行。 只需添加一些更详细的异常处理;)。

public partial class MainWindow : Window
{
    public MainWindow()
    {
        InitializeComponent();
        DataContext = this;
        Task.Factory.StartNew(() => DoTheMagic());
    }

    // Here the magic occurs
    public async Task DoTheMagic()
    {
        while (true)
        {
            string url = "http://query.yahooapis.com/v1/public/yql?q=select%20*%20from%20yahoo.finance.quotes%20where%20symbol%20in%20(%22YHOO%22)&diagnostics=true&env=http://datatables.org/alltables.env";
            string raw = await GetResponse(url);
            var parsed = await ParseXml(raw);

            // Pass results to UI
            Dispatcher.BeginInvoke(new Action(() =>
                {
                    if (parsed == null || !parsed.Any())
                        return;

                    var now = DateTime.Now;
                    foreach (var tuple in parsed)
                        textBox.Text += string.Format("{0} {1} = {2}{3}", now, tuple.Item1, tuple.Item2, Environment.NewLine);
                }));
            Thread.Sleep(3000);
        }
    }

    // Get response from service
    public async Task<string> GetResponse(string url)
    {
        string content = null;
        try
        {
            var request = WebRequest.Create(url);
            var response = await request.GetResponseAsync();
            var stream = response.GetResponseStream();

            if (stream == null)
                return null;

            using (var reader = new StreamReader(stream, Encoding.GetEncoding("utf-8")))
                content = await reader.ReadToEndAsync();
        }
        catch
        {
            System.Diagnostics.Debug.WriteLine("ZOMG!");
        }

        return content;
    }

    // Parse response with your logic
    public Task<List<Tuple<string, string>>> ParseXml(string xml)
    {
        return Task.Factory.StartNew(() =>
            {
                try
                {
                    var nodes = new string[] { "Symbol", "Ask", "Bid" };
                    var result = new List<Tuple<string, string>>();

                    using (var reader = new XmlTextReader(new StringReader(xml)))
                    {
                        reader.MoveToContent();
                        while (reader.Read())
                        {
                            if (reader.NodeType.Equals(XmlNodeType.Element))
                            {
                                if (nodes.Contains(reader.LocalName))
                                    result.Add(new Tuple<string, string>(reader.LocalName, reader.ReadElementContentAsString()));
                            }
                        }
                    }
                    return result;
                }
                catch
                {
                    System.Diagnostics.Debug.WriteLine("I haz exception!!1");
                    return null;
                }
            });
    }
}

输出

notfound

答案 1 :(得分:0)

线程退出是正常的,请查看退出代码:

The thread '<No Name>' (0xe3c) has exited with code 0 (0x0).

每次定时器触发时都会发生这种情况,并且从输出看起来定时器正在定期触发(你有多个线程退出,显然是定期)。您可能希望在异常处理程序中放置一些内容而不是仅仅使用它们,然后您可以设置断点并查看后续调用计时器处理程序无法运行代码的原因。