0

I've been working on this for about 8 months. It's been an annoyance more than anything until recently when I moved from a DataSet / DataTables to lists. Now the problem is a lot more prevalent (I think because the lists appear to be a LOT more efficient).

This question has been asked a few times but none of them really hit on what truly is going on (nor are any of them answered). The odd thing is I can't isolate where in my code this is causing the exception as the debugger pulls up the program.cs which only has this code:

    [STAThread]
    static void Main()
    {
        Application.EnableVisualStyles();
        Application.SetCompatibleTextRenderingDefault(false);
        Application.Run(new MyApp());

    }

The application exception is on the Application.Run... line.

I'm using the DataGridView as a back ground processing log display. I have numerous background processes in a service that communicate back up to a winform app. The form listens for these messages (event handler / signalr) and also remove messages (like a FIFO queue) to not exceed a maximum defined amount in a list then I process the message and sort them into a BindingList[]. Then in the datagrid if I click on an item, it will display the full message in a textbox. I have multiselect turned off and again, the datagridview is read only.

Oh also, the BindingList[] is bound / rebound to the datagrid from another control so I can select which list to display in the datagridview. This is not the issue as I've isloated the issue by forcing a single specific list in the code and still have the problem.

To get this to crash, I can click on datagrid numerous times and eventually it will crash. If I really want to crash it quickly, I click on the datagridview and scroll (keyboard arrow) down and up and I can crash it in a few seconds.

I found this article (click here) on StackOverflow that describes what is going on. And in one of the comments it refers to a Microsoft Bug Report(click here) which stats this is by design! However, most are talking about manipulating the cells which I am not doing. The top message is nearly identical to what is happening to me but the programmer is using an inherited DataGridView so his solution will not work for me.

This does have to do with adding and or deleting items from the BindingList. I can get it to crash if I have either of the going on while scrolling / selecting in the DataGridView. But that code is very simple:

    private void DelRow( string szTableName)
    {
        try
        {
            int nProcQueue = qdList.Queue(szTableName);
            MsgQueues[nProcQueue].RemoveAt(0);

            this.BeginInvoke(new MethodInvoker(Refresh_dgvDetail));
        }
        catch (Exception ex) 
        {
            LogEx(ex); 
        }
    }

and

    private void AddRow(LogObject oLogObject, string szTableName)
    {
        try
        {
            int nQueueNumber = qdList.Queue(szTableName); // helper object to return queue number based off the name of the list

            MsgQueues[nQueueNumber].Add(oLogObject);


            this.BeginInvoke(new MethodInvoker(Refresh_dgvDetail));
        }
        catch (Exception ex) 
        { 
           LogEx(ex);
        }
    }

This really seems like a c# bug... Why MS would have this as designed is beyond me...?

Anyone know how to stop this behavior?

Zonus
  • 2,313
  • 2
  • 26
  • 48
  • Is 'MsgQueues' the thing that is visible in your datagridview? – grek40 Jun 09 '17 at 14:00
  • Those are the BindingLists[] that I set in the DataSource= for the DGV, yes. – Zonus Jun 09 '17 at 15:25
  • What about moving the `RemoveAt(0)` respective `Add(oLogObject)` calls into the `BeginInvoke(...)` function? Might be better to execute this change in the same thread context as the following refresh... – grek40 Jun 09 '17 at 15:31
  • I've already tried that with no success... – Zonus Jun 09 '17 at 15:42

2 Answers2

1

Grek40, you're right; I was wrong. I did the MethodInvoker for just the add; not the delete. It had to be done for both. Basically anything method that touches the datagridview needs to have MethodInvoker. This is an example of what I did:

this.Invoke((MethodInvoker)delegate { MsgQueues[nCurrentQueue].RemoveAt(0); });

Problem went away.

Zonus
  • 2,313
  • 2
  • 26
  • 48
0

Set the column on the side to ReadOnly = true;