Click here to Skip to main content
15,884,537 members
Please Sign up or sign in to vote.
0.00/5 (No votes)
See more:
Hello everyone,

Here's my situation, I have an application that spawns windows that display financial data with the dataGridView. My data structure (bindingList) is bound to the dataGridView. My apps is receiving anywhere from 500 to 2000 message per/min. The messages are coming from another thread so I have invoke my control on the correct thread (Control.BeginInvoke()) I notice when I have more than one window open and messages are coming in at a rate of 2000 per/min, only the window that has focus is updating! Can someone please explain to me what's going on and if there is a solution to this?

public delegate void UpdateDataTblDel(MyMsgType msgType, MyData data);

public class Main: Form
{ 
   MyDataFeed dataFeed = new MyDataFeed();
   DataTable dataTbl = new DataTable();

   public Main()
   {
     Init();
     
     CreateColumns();

     dataFeed.Data += new DataEvntHndlr(DataHandler);
   }
   
   private void CreateColumns()
   {
      DataColumn col;

      col = new DataColumn("ID");
      col.DataType = System.Interger;
      dataTbl.Columns.Add(col);

      col = new DataColumn("Price");
      col.DataType = System.Double;
      dataTable.Columns.Add(col);
      
      DataColumn[] primaryKey = new DataColumn[1];
      primaryKey[0] = dataTbl.Columns["ID"];
      dataTbl.PrimaryKey = primaryKey;
   }

   private void DataHandler(MyMsgType msgType, MyData data)
   {
      this.BeginInvoke(new UpdateDataTblDel(UpdateDataTbl), new object[] {msgType, data});
   }

   private void UpdateDataTbl(MyMsgType msgType, MyData data)
   {
      DataRow row = null;
      
      row = dataTbl.Rows.Find(data.ID);
      
      if (row == null)
      {
          row = dataTbl.NewRow();
          row["ID"] = data.ID;
          row["Price"] = data.Price;
 
          dataTbl.Add(row);
      }
      else
      {
         if(msgType == MyMsgType.Remove)
         {
            row.Delete();
         }
         else
         {
            row["Price"] = data.Price;
         }
      }
   }

   private void button_Click(object sender, EventArgs e)
   {
      View view = new View(dataTbl);
      view.Show();
   }
}

public Enum MyMsgType
{
   Remove,
   Add,
   Update
}

public class MyData
{
   public double Price;
   public int    ID;

   public MyData(double price, int id)
   {
      Price = price;
      ID = id;
   }
}

public class View : Form
{
   public View(DataTable dataTbl)
   {
      Init();

      dataGridView.DataSource = dataTbl;
   }
}


Thanks in advance,
-DA
Posted
Updated 6-Jan-13 7:44am
v9
Comments
Sergey Alexandrovich Kryukov 5-Jan-13 2:25am    
Explain? Without your code sample? Hm...
—SA
d.allen101 5-Jan-13 2:34am    
SA it's too much code to post. if I could attach a sample project I would but I can't do that can I?
Sergey Alexandrovich Kryukov 5-Jan-13 2:37am    
Too much? Well, did you know that there is no such thing as a miracle? :-)
And I explained hundreds of times: it makes sense to develop a code sample specifically for asking a question. Not your existing code.
—SA
Sergey Alexandrovich Kryukov 5-Jan-13 19:41pm    
Hardly, because that page is removed.
—SA
sariqkhan 6-Jan-13 5:05am    
http://www.codeproject.com/Questions/522502/passingplustheplusdataplusfromplustextboxplustoplu
this is the one

Alen,

OK, I got it. Looking at how intensive your data exchange is, I seriously doubt that the whole architecture is reasonable. But, as I don't know the ultimate purpose of all this activity, I cannot advise anything particular to improve it.

At the same time, the idea to infinitely populate an instance of a DataGridView, especially of relatively high rate won't work for you anyway, no matter how much effort would you pay to "optimize" it. Did you think that sooner or later, it may happen that all of your available RAM will be not enough to hold your UI?

So, there can be different approaches; and I cannot overview them by the reason I explained above. So, the first principle you should embrace is: the UI user never needs to see all messages at once. Once you understand it, you will be able to design you UI in a reasonable way.

So, first of all, you should not update your DataGridView, even if you use one as data is received. Instead, you should have one small control which is update when each message comes. For example, if could show just three-four data elements, say, current number of messages, two points of time: for a very first and the last received messages; and, maybe also something like ID (name, description, you name it) of your most recently received message, only one.

First of all, as your first action on receiving messages, you should dump all received messages on disk; you just have no other choice. The data should be represented as it is received and as the user decides to look at it.

The user should be able to select what range of messages to look at. One (not so simple) approach would be using the same very DataGridView instance, but in virtual mode:
http://msdn.microsoft.com/en-us/library/system.windows.forms.datagridview.virtualmode.aspx[^],
http://msdn.microsoft.com/en-us/library/2b177d6d.aspx[^].

The user will have an impression of all the available data is available at once, but the range of messages should populate only the visible part of grid view as the user scrolls it. This is a very usual solution for big volumes of data.

—SA
 
Share this answer
 
v2
Comments
d.allen101 6-Jan-13 13:49pm    
Actually my dataGridView is not growing infinitely large I do delete entries too. Forgot to include in my sample app, I've updated my code sample so you can take a look. The issue I have is I can't write the data to disk and let the user determine when and how data they want to view. This is a real-time stock market trading application and as far as implementing dataGrideView in virtual mode I'm grid is dealing with enough rows to need virtual mode. at most i'm have a couple 100 rows but normally it's a lot less than that.
Sergey Alexandrovich Kryukov 6-Jan-13 13:59pm    
I understand but I'm pretty sure that you should use some approach according to my advice anyway. The problem is not that you are storing data infinitely. The problem that you wanted to present too much data at once and update UI way too often. Not only it can be unbearable burden to the client part, it is also way too redundant. It does not make sense.

If you follow my advice, you could be able not to remove messages, at least for long time, if you would need it, of course.

Think about it. This is really a way to go.
And thank you for the effort to clarify things (last portion a big late, but still... :-) and create a code sample; generally, it's always helpful.

—SA
d.allen101 6-Jan-13 14:04pm    
You're absolutely 100% right! My issue is updating the grid too much and a lot of it un-necessary updates. I understand what your explaining too me but have no idea how to go about implementing this correctly. Can you give me an example and how it would apply to my design or exactly what things I need to change in my design?
Sergey Alexandrovich Kryukov 6-Jan-13 19:13pm    
OK, you can read about virtual mode and implement it according to the guidance.

Perhaps, you need a better understanding how to implement temporary message storage in disk. You will need to use two files: index file and message file, keep them open all the time (use Dispose), a lock object to use in lock statement; only message file read/write operation should be locked because only this file is used in both thread; you need to use the same serialization used in message delivery (abstract out stream); the access to a message by index should be used by the GridView; and you should implement it as an index property and you better encapsulate it all in one class and make the files and other detail private.

Is all of it clear, or you would need some help on it? — I can explain it all...

—SA
I faced same-thing on my past application as there ware auto update functionality.

You need to use DataTable with Primary key instead of BindingList

Using DataTable with PK you can find and update respected row on DataTable and data will be refresh automatically on grid

Kindly try above or know me if you have any query so I can provide you sample code for same. :)
 
Share this answer
 
Comments
d.allen101 5-Jan-13 3:08am    
i tried that and it didn't help at all (same results). i'm working on some sample code to post now...
URVISH_SUTHAR1 5-Jan-13 3:10am    
I'm sure this will done with DataTable or Generic list with BindingSource only.

Kindly provide me your sample app so will update you soon :)
d.allen101 5-Jan-13 4:36am    
just posted it
sariqkhan 5-Jan-13 7:15am    
http://www.codeproject.com/Questions/522502/passingplustheplusdataplusfromplustextboxplustoplu

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900