0

I'm updating my cells values from Yahoo's "Stock API". It works like a charm everything is updating properly , but when the updates are performed which is almost all the time since their in a timer with an interval at 3000 milliseconds. How can I get rid of this problem?

I tried suspending the layout and resuming, without success.

This is my own little teaching myself kinda project, so keep in mind that I never had anything with xml or datagridview to do before.

        private void timer2_Tick(object sender, EventArgs e)
    {

        try
        {
            if (!(dataGridView.Rows[0].Cells[0].Value == null)) // Updates the rows idividualy as long as first row is not empty
            {
                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";
                        dataGridView.ResumeLayout();
                        dataGridView.Update();
                        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)
                            {
                                dataGridView.Rows[i].Cells[dataGridView.Columns[t].Index].Value = "-"; 
                            }

                            // 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)
                            {
                                dataGridView.Rows[i].Cells[dataGridView.Columns[t].Index].Value = "-";
                            }
                            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)
                                dataGridView.Rows[i].Cells[dataGridView.Columns[t].Index].Value = reader2.ReadString(); // 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();
                            }

                        }
                    }
                }
            }
        }
        catch (XmlException)
        {
        }
    }
BenMorel
  • 34,448
  • 50
  • 182
  • 322

1 Answers1

0

You better to request data update from Yahoo in a separate thread because it is taking long time. You can use System.Threading.Timer for that purpose.

Vasily Semenov
  • 302
  • 3
  • 6
  • I'm not famailiry with threads, how do you mean? That i should do catch all the values in another thread and then update them by sending them over to the timer? ( i looked at http://stackoverflow.com/questions/12796148/working-with-system-threading-timer-in-c-sharp ) – MattiasLarsson Feb 19 '14 at 20:53
  • Yes. You should grab all the data from Yahoo in a separate thread and after that update them on a screen. The way how you implement it now reading the data from the web for every cell in your grid and it takes a bunch of time. The main application thread become locked during these operations. For example you can fill some sort of dictionary in a separate thread and after that invoke an Update method (you need to write it too) with a dictionary as parameter. – Vasily Semenov Feb 19 '14 at 21:13
  • Or you can execute the function yo have in a separate thread. In that case you need to wrap all your cell updates in a BeginInvoke((Action)delegate() { dataGridView.Rows[i].Cells[dataGridView.Columns[t].Index].Value = #ALREADY_READ_VALUE#; }); So your line of code dataGridView.Rows[i].Cells[dataGridView.Columns[t].Index].Value = reader2.ReadString(); should be changed to string val = reader2.ReadString(); BeginInvoke((Action)delegate() { dataGridView.Rows[i].Cells[dataGridView.Columns[t].Index].Value = val; }); – Vasily Semenov Feb 19 '14 at 21:18
  • Or, if you execute the function you have in a separate thread, you can define string val = string.Empty; at the beginning of you second loop, replace all the lines where you assigning value to the grid cell with a val = #NEW VALUE#; and at the end of that loop call BeginInvoke((Action)delegate() { dataGridView.Rows[i].Cells[dataGridView.Columns[t].Index].Value = val; }); – Vasily Semenov Feb 19 '14 at 21:28
  • Okey this was very complicated, beyond my level of knowledge i'm going to read some about this before i get to into it. Thanks. – MattiasLarsson Feb 20 '14 at 09:02