There are several options you can take here. First, you can set up double buffering in a form that finishes drawing all updates on the underlying bitmap, and then displays the newly drawn image (instead of individually drawing controls on a graphic object). With this method, I saw a speed increase of 50%. Throw this into the constructor:
this.SetStyle( ControlStyles.AllPaintingInWmPaint | ControlStyles.UserPaint | ControlStyles.DoubleBuffer,true);
Another thing to keep in mind is that string concatenation is SLOW for large amounts of data. You better use StringBuilder to create the data, and then just show it with StringBuilder.ToString (although itβs even better to deploy updates, perhaps every 100 iterations). On my machine, just modifying it to add to StringBuilder, it lasted from 2.5 minutes to iterate 10k to about 1.5 minutes. Better, but still slow.
new System.Threading.Thread(() => { for(int i = 0; i < 10000; i++) { sb.AppendLine(DateTime.Now.ToString()); Invoke((Action)(() => { txtArea.Text = sb.ToString(); txtArea.SelectionStart = txtArea.Text.Length; txtArea.ScrollToCaret(); })); } }).Start();
Finally, just a proven stunning (threw one conditional code into the above code, just before invoke invocation), and it finished in 2 seconds. Since we use StringBuilder to actually build the string, we still save all the data, but now we only need to make updates 100 times, not 10k times.
So what are your options? Given that this is a WinForm application, you can use one of the many Timer objects to actually perform user interface updates for that particular control, or you can just keep a count of the number of βreadsβ or βupdatesβ for the underlying data (in your case, a stream) and only update the UI by X the number of changes. Probably using the StringBuilder option and incremental updates is the way to go.
source share