2014-02-24 67 views
0

因此,我啓動線程計時器,它的工作方式,但線程計時器中的方法從yahoo API讀取XML,有時對服務器的響應不好,因此引發了XMLexception。但它似乎停止了線程或某事,因爲線程開始良好,但是當拋出異常時,所有線程都停止。那麼有什麼不對,我可以在每次停止另一個時啓動一個線程?因爲所有的線程停止,然後沒有線程開始agiend。線程停止,XMLexception錯誤

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

     } 

TimerHelper(object obj)有try 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(object 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). 

它爲什麼退出?

+0

你是如何從雅虎API讀取XML的?你使用webclient或httprequest或其他東西?是否可以顯示代碼? – Steve

+0

Httprequest [鏈接](http://query.yahooapis.com/v1/public/yql?q=select%20*%20from%20yahoo.finance.quotes%20where%20symbol%20in%20(%22YHOO%22) %0A%09%09&diagnostics = true&env = http%3A%2F%2Fdatatables.org%2Falltables.env)@Steve – MattiasLarsson

+0

你是否在ASP.NET中執行此操作。如果是的話,它可能會被線程池回收,因爲退出代碼都是0 – Steve

回答

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

+0

是的,當然我不想讓它們退出,但爲什麼線程計時器停止創建線程過了一會兒 ? @mikkoviitala – MattiasLarsson

+0

按照我的文章中的鏈接,@MattiasLarsson,按照鏈接:)。我想可以幫助你http://stackoverflow.com/a/3635896/1061668(也許) –

+0

我試過(新線程((TimerHelper)=> {}){Name =「Time」})。開始();沒有工作,輸出:線程'時間'(0xf88)已退出代碼0(0x0)。沒有更多,它似乎甚至沒有運行TimerHelper(); – MattiasLarsson

0

線程退出是正常的,看的退出代碼:

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

這是將要發生,每次定時器觸發,並它看起來像從你的輸出中看到,定時器是週期性地觸發的(你會得到多個線程退出,顯然是每個線程iodically)。您可能希望在異常處理程序中添加某些內容,而不是僅僅使用它們,然後您可以設置一個斷點並查看後續對定時器處理程序的調用無法運行代碼的原因。

+0

我想開啓一個新線程,當線程結束時,我想開啓一個新線程,讓繼承人總是運行一個,只有一個是可能的? @BlackICE – MattiasLarsson

+0

爲什麼你甚至使用計時器呢?只需製作一個永不終止的循環,並在再次開始循環之前睡眠100ms或其他東西。使用後臺工作線程調用此方法。 – BlackICE

+0

因爲我已經嘗試過和普通的定時器,這些解決方案的問題是,當方法運行時,它會鎖定gui,我已經在altredy詢問了這個在Stackoverflow(檢查我的配置文件) – MattiasLarsson