WinForms Invoke/BeginInvoke - c#

I have a C# win form where I read a file and show lines in a datagridview. Everything works fine.. and I use delegate and Invoke for displaying the lines as they are being read. It also shows a progressbar and does some other stuff like calculating line length and parse the lines to extract certain fields from each line.
Just curious, if anybody has tried this kind of implementation. Currently my app reads a 250MB file (having ~ 12000 lines) in little over 3 minutes (Win 7 32bit/celeron 2.66Ghz/4GB). I was wondering if it is possible to reduce the time - more of like by changing the way I implemented it.

Well, you're quite right to have second thoughts about this. What's probably the toughest read possible, War and Peace by Tolstoy, has roughly half a million words. What you're dumping to the screen is a hundred times more. It doesn't really matter how long it takes to put this much info on the screen, it will take your user a wholeheckofalot longer to even scroll through it.
I personally hesitate to ever put anything more than, oh, 50 items in a list. 100 tops. Beyond that, it becomes sheer torture for a human being.
To get there, allow your user to filter content, gradually drilling down in the huge result set to a relevant item. Exactly what that ought to look like is not clear from your question. Think about it for a bit, I'm sure you'll come up with something.

Ok...I love these questions. Why are you showing a user 250mbs of data in a data grid? There is NO WAY that an end user can process understand 250mbs of data in a grid. If the end user is pressuring you for this feature you need to address it with them from a "this is a bad idea" standpoint. Performance problems can usually be solved in most cases by educating the user. :-D

First, you need not load the entire file, nor display it. You can load portions of it for display. i.e. in the grid, you cannot show the enire file anyway, the screen is only so big. Consider loading only what you display (plus a few extra lines for smooth scrolling) and load the rest on demand as the user is scrolling through the content. The user will be unaware that the file is only partially loaded.
Even nicer would be if you have some logical grouping, in a book you could display the chapters, in a financial type application, either by account or time period.

Maybe something like VirtualMode can helps you:
Virtual mode is designed for use with very large stores of data. When the VirtualMode property is true, you create a DataGridView with a set number of rows and columns and then handle the CellValueNeeded event to populate the cells. Virtual mode requires implementation of an underlying data cache to handle the population, editing, and deletion of DataGridView cells based on actions of the user. For more information about implementing virtual mode, see How to: Implement Virtual Mode in the Windows Forms DataGridView Control.
P.S. About performance: no one except profiling tool can't helps you to solve any performance-related problems.

Related

How should I manage my screens in WinForms?

So I'm rewriting a windows forms project.
The old project had few issues. These are some I'm trying to fix right now.
My problems:
Everything was on panels on one form. Switching screens in the code was done by hiding/unhiding these panels.
General slow performance across screens.
Poor data coupling.
My solutions:
Break up screens into user controls (hereon just refered to as 'screen(s)'). My main form has 3 components on it, a nav bar, title bar and 'view port'(an empty, docked, panel).
I will keep only one screen/user control (hereon just refered to as 'screen') in memory and docked in the view port. This is done by just initializing a screen and popping it into the view port panel on the main form. Changing screens will simply be destroying the current screen in the view port and initializing a new one in it's place. This isn't to reduce memory usage but rather active components, as what I understand, slows down the old winforms project, is the fact that winforms uses the cpu to render.
This is where the subjectively fun part comes in. If a controller/presenter(from mvc/mvp type patterns)/code changes business data, the screen that is displaying that data needs to be updated. Since there will be only one screen displayed at one time, I will now need to go check if the screen affected by the data is currently initialized and update the screen. I think checking which screen uses a piece of data and checking if that screen is active and then changing the appropriate visual component, for each piece of data will be moronic.
So when I initialize a screen I will just bind (with data binding) all of it's controls to my global state. This feels perfect since I will have some services impacting my state with their own controller, and the changes will be handled the same as a ui event changing the data. This is also great since my data layer will need to propegate to rather (for me) complex databases, so keeping the data layer clean will help.
My questions:
Am I managing my screens properly? Is it a good solution to slow performing winforms software?
Should I use data binding to achieve this? In this case it will be my sole source of view data, and I've read that data binding should be used in moderation. What am I missing.
I'm quite green and this job is my first C# bout. Although I have done java and flutter/dart before.
Also if there is a better place to ask these types of questions, I would appreciate a point in the right direction. There isn't any/other/senior/superior software engineers at work who I can ask these types of questions.
Working with relatively complex software, communicating over ethernet with hardware devices here.
I prefer having many many small windows that save their position when closed and restore their previous position when opened so that users can arrange them as needed.
Since I work with relatively slowly updating data, I periodically keep updating the data in the controls, unless they are focused (eg. potentially currently being edited).
Sure, with this, the data might be inconsistent sometimes, but no one will notice in the 50ms timeframe until the next update.
Since this is done for practically all my controls, the logic can also be centralized beautifully.
This, of course, goes against the binding paradigm but it's my development style which also works well for other programming languages.

WPF: Best suited UI element to display a lot of text?

I'm currently working on a C#/WPF program where I'm displaying a lot of text data(replaying a text log). This runs on a timer that reads from text files and then sends the data to a User Control that will display them. The problem I'm having is that it takes more than one second to display the data that covers said second(due to the amount of data, ~11k lines pr second) in the TextBlock I'm using. If I skip the displaying part the timer/program runs just fine without any delays.
What is the best UI element to display this amount of data with in regards to update speed?
With large data, you are almost always better off if you paginate the results.
This is the approach google takes with their search results. You get millions but only a fraction are on the first page.
Microsoft gives you the tools to accomplish this - FlowDocument
You can very quickly get professional looking reader style output, like a Kindle screen.
Try AvalonEdit which is great at handling large data, unlike TextBox/Block which makes UI unresponsive when dealing with large data. http://www.codeproject.com/Articles/42490/Using-AvalonEdit-WPF-Text-Editor
Are you sure users would need the entire data? You can alternatively just show the tail of logs (e.g. last 100K lines) and provide a link to download the entire text or some kind of paging mechanism.
You could create a collection of your log messages / strings / lines, and use them as the itemssource of a virtualizing panel, such as the Listbox uses it by default. Only those messages that are actually in the field of view will be rendered.

c# what wpf control to use for showing text file

Whats the best control to use in wpf applicaion for loading big text files into? And its not just simple as that, i need to be able to hightlight/change background/color of some lines. I was thinking of using RichTextBox.. but though i just come and ask what other people think.
I dont need to edit the text, just highlight lines with errors
EDIT: Ah i forgot to mention, text file content is processed by the program what will change the background color of some lines. Would be nice to give user a change to do that allso when the program failes to find some error lines.
EDIT2: The application is for parsing log files, so the files might be big, over 50 000 lines..
I didn't understand if you only want to display files or allow user to edit them.
Either way, maybe ScintillaNET would be useful to you.
Well known text editor, Notepad++ uses Scintilla :)
You could grab notepad++ sources at http://sourceforge.net/projects/notepad-plus/, but It's written in c++, so the API would be a bit different than in .NET.
EDIT
Notepad++ is capable of displaying files of around 100-200MB. If you need better than that, you would need to implement some kind of paging technology/virtual mode (do not load entire file, only the portion that would be displayed on the screen depending on current scrollbar position)
If Scintilla seems an overkill, then maybe you'd be better off with simply building a DataGrid. If log entries consist of several fields, these could become columns and would be even easier to read. If you want to go that route, first parse your log file into a List of LogEntry, then use databinding to bind to it. You could read your file incrementally as new lines get added for better user experience.
I think RichTextBox will be most appropriate in this case but as CharithJ said you cannot load whole log in to it at one time it will be too much performance hit.
What I would do in scenario like this is .. I will have a Richtextbox along with two small up and down buttons for kind of scroll. I will only load some text of log at one time let's say x number of characters. Once user clicks the up or down scroll button, I would remove some text from start and end depending on which button user have clicked, up or down and based on that I would remove some text from richbox and append some other.
Either you can do something like I suggested above, or one other way could be to extend the RichTextBox control and implement logic that only forwards a limited text to RichTextBox for display at a time. You can handle scroll related events to make changes in RichTextBox's content.

Increase Performance of DevEx WPF Grid

I'm using the DevEx DXGrid (WPF) to show about 2,000 rows of data. I'm using a DataRow Template to get Master-Detail behavior (a new detail grid for each row).
My application responds extremely slow to almost all use input (to the grid). for example:
scrolling
expand/collapse group rows
resize app window
I've contacted DevEx support about this - but they say the solution is non trivial and they are waiting until next major version to 'fix' this.
Have you found any solutions to these problems? I'm hoping there is a way to structure xaml or code to avoid some of the performance problems. I'd be very interested to hear what performance problems you've encountered with the DXGrid and how you solved (or not) them.
thanks.
Indeed, we have changed the way the DXGrid works and it should operate faster. However, this improvement will be only visible in 10.2 and it relates the expanding / collapsing group rows.
If you have problems with scrolling, please post a sample project in the support center showing your performance issues. We will try to improve the control based on your particular situation.
As a general rule of thumb, simply put: the less controls, the faster it will be.
When using the GridControl, you may want to look into using the CellDisplayTemplate and use a very lightweight control to display the content of the cell, and then use the CellEditTemplate for your heavier edit control, as the CellEditTemplate is not is not loaded until the user enters the cell. This becomes very powerful the bigger your GridControl is.
See 3 or 4 for more info on GridControl optimization.

How can I play with databinding to a desktop application like in web-based application

I've a form and I'm doing databinding of my datagridview in the event "form load", the problem is, that the form takes a little (or a lot depends on the size of information) to load, because my data has a lot of binary information (photos) to binding there.
In some sites, we can see a picture saying "loading", which is cool and is good to the user, because I knows that is loading and not stoped. So, I wanted to simulate something like that to desktop application when I'm doing databinding to the table, can you help me?
You can't do much about the actual binding itself, since forms have thread affinity. However, you can load the data (from the database or where-ever) on a separate thread - look at BackgroundWorker, for example.
If the db-load is fast, but the binding is slow, you can look at things like "virtual mode" that exists for many standard list-based controls. This can reduce the time taken to bind by only looking at the immediately visible data.
Other than that, you can do things like changing the cursor, showing a splash on another thread, etc. It really depends where the time is being spent (have you profiled?).
You could show the 'loading' form in a different thread.
Also consider hard whether you need all of the data loaded with the form - could any of this data be loaded after the form load?
Try and give your application a feeling of perceived speed.
Sometimes is not our decision to load the data after a user action. My client wants the data loaded without user action.
Thanks you for your answers :)

Categories