Reputation: 5767
I have a Windows Form app written in C#. Its job is to send messages to a list of users. While those messages are being sent, I'd like to display status of the operation for each user. What I am doing (for each user) is creating a Label control and adding it to Panel. This works without a problem for a small set of users. When I increase the size to 1000 or more, the Visual Studio Debugger displays the following message:
A first chance exception of type 'System.ComponentModel.Win32Exception' occurred in System.Windows.Forms.dll A first chance exception of type 'System.Reflection.TargetInvocationException' occurred in mscorlib.dll
And then the application hangs. Any thoughts on what I'm doing wrong and how I can fix this?
Upvotes: 1
Views: 1972
Reputation: 21591
I like to use ListView
in details mode. Usually, I'll make a routine for adding a row, make it selected, and call EnsureVisible()
on the item to autoscroll to it.
Like already mentioned, controls correlate to one or more window handles and the OS can only hand out so many.
Upvotes: 1
Reputation: 75296
Put a ProgressBar on your form instead. If you're sending one message to 1000 people, just increment the ProgressBar by 1 each time you send a message.
If you're sending 5 messages to 1000 people, have one progress bar for messages and one for people (the second bar will cycle through its values once for each value on the first bar).
You can also have a label for each progress bar (saying "95% complete" or "Message 3 of 5" or whatever).
You can't have such a large number of controls on a .NET form, and even if you could, there's no way any user could look at them all at the same time anyway.
Upvotes: 1
Reputation: 4971
If you are literally only showing labels in the panel, I would suggest that you show the statuses using GDI. Write the text of the visible area in OnPaint and invalidate the area of a status label only when it changes.
Upvotes: 0
Reputation: 9483
Without seeing specific code, it is difficult to tell. If I were tasked with the same program, I would approach it differently.
I would use a Grid or a Listview to display the user and the status of his or her message being sent. These controls can handle an unlimited(well -- limited by system memory) number of rows. One row per user (or one row per message -- which ever works better).
That should be the only thing going on in the UI thread. Use a background worker (BacngroundWorker class), or a message queuing framework (MSMQ, SQL server) to have the messages sent asynchronously and report on the status back up through the BackgroundWorker.
As for your specific error -- I do not know why you are getting it. There should be no limit to the number of labels you can put on a WinForm. I suspect the error is caused by something else.
Upvotes: 1
Reputation: 41266
Too many controls! Make a single control to contain all those status messages. How about a multi-line textbox?
Upvotes: 0
Reputation: 50215
Given the size, I would consider displaying your status in a RichTextBox.
What is happening is that you are generating too many handles and the Framework can't handle them all.
Upvotes: 3
Reputation: 415630
This is kind of a work around, but I don't think your users really want to look at a list of 1000 people. Show them the current/most recent and summary report for the rest. Or let them page through it.
Upvotes: 2