views:

131

answers:

2

I am writing a packet analysis app using C# and putting the packets coming from network in the datagridview, but once it starts populating, datagrivdview scrolling becomes like shown below in the image and I am unable to score? How I can fix this?

Basically the problem is that the data is coming in very fast so maybe it's not able to handle it?

alt text

I am populating the data manually and here is the code:

string[] row = { packetsList[countOfPacketCaptures].packetType, packetsList[countOfPacketCaptures].sourceAddress, packetsList[countOfPacketCaptures].destinationAddress, packetsList[countOfPacketCaptures].sourcePort, packetsList[countOfPacketCaptures].destinationPort, packetsList[countOfPacketCaptures].packetMessage };

dgwPacketInfo.Rows.Add(row);
+2  A: 

How are you populating the entire DataGridView? Perhaps you should try using it in virtual mode, which means that the DataGridView will ask you for the data in the visible range and only ask for data when it needs it.

Are you doing the population on the main UI thread, or a background thread? If you are tying up the main thread with work, your UI will become sluggish.

I would suggest that you implement a list behind the scenes and add your data to it from a background thread. Consume the events associated with virtual mode (see this walkthrough), and supply data from the list. When you update the list, you will need to refresh the DataGridView (on the main thread, since the DataGridView requires this).

I'm not sure how many packets you are seeing a second, but perhaps you should buffer them and only refresh the DataGridView once every 10 packets or once every one second (or whatever number makes sense in your case) to keep the UI responsive and not overload it with refreshing.

private delegate void ParameterlessVoid();

private void RefreshDataGridViewThreadSafe()
{
    if (this.dataGridView.InvokeRequired)
    {
        this.dataGridView.Invoke(new ParameterlessVoid(this.RefreshDataGridView));
    }
    else
    {
        this.RefreshDataGridView();
    }
}

private void RefreshDataGridView()
{
    this.dataGridView.Refresh();
}
Zach Johnson
Well this is how i am adding data.string[] row = { packetsList[countOfPacketCaptures].packetType, packetsList[countOfPacketCaptures].sourceAddress, packetsList[countOfPacketCaptures].destinationAddress, packetsList[countOfPacketCaptures].sourcePort, packetsList[countOfPacketCaptures].destinationPort, packetsList[countOfPacketCaptures].packetMessage }; dgwPacketInfo.Rows.Add(row);
itsaboutcode
A: 

Take your problem to the extreme. What happens when you get 50,000 new items each second? Do you want to show all that data? Does it make sense to show all that data? Is the user wanting, or even able, to view all that data?

Manually filling the grid (or any similar control, like a ListView) is likely not going to work for your needs, unless you find a way to filter out unnecessary data. If you were viewing packets on only one port, for instance, or wanted to only view data from a specific machine, your method might work.

I second Zach Johnson's answer - consider showing your data virtually. Your users will thank you.

Charlie Salts
Well when i make data virtually option to true, it display nothing! Secondly its requirement of my client to display data as its coming, like wire shark.
itsaboutcode
@itsaboutcode: You have to consume the events associated with virtual mode and set the row count in order for a virtual mode DataGridView to show anything.
Zach Johnson
@itsaboutcode: Setting a Designer property to true isn't going to write your code for you! **Read** the links provided in Zach's answer.
Charlie Salts