Improving WPF application performance with UI being updated every 100ms - c#

I have a WPF application. I would like to explain the working of the application. The application is used for monitoring data that is received over network through UDP, every 100 ms. In the application's main window, another thread is started in which the UPD packets are received and parsed. After the data is parsed, the packet based on packet ID is updated to UI through dispatcher. There are 5 windows with a browser control, couple of charts and text boxes in each window.
The UI rendering is slow and application responsiveness reduces when more than one window at a time is updated. What is the best way to improve the performance of the application? Is it good if each of the window is created in a new thread? If each window is created in a new thread, I have noticed that some data is missing in the UI. Moreover, setting the owner of these windows to the main window is also not possible which is proving to be a problem.

Related

How to control a separate WPF application?

I'm developing a Revit add-on which performs some lengthy tasks. During the process, I want to display a simple WPF window with an indeterminate progress bar, a label to inform about current process and a button to enable aborting.
I already tried the most obvious ways of accomplishing that: creating a WPF window inside the add-on and displaying it, but the problem is that the UI gets frozen, no matter how I implement this. During some processes, the whole Revit UI gets frozen/white so I really wouldn't expect my embedded WPF window would behave normally in these conditions anyway.
The workaround I figured out was to have the WPF window as a separate app (EXE file) I could run from the add-on. I based my implementation on this example .
The good part of it is that it doesn't hang no matter what is happening with Revit.
The bad part is that the sequence of how Windows is queuing the calls of my separate WPF app is sometimes different from the sequence of these calls from my add-on. It sometimes results in a situation when the Revit process is over but the WPF window is still displayed (waiting for the final, closing call which had been apparently already executed, but then the app got reactivated with another, delayed call).
Preferably I would like to handle the WPF app the same way as you can i.e. handle an Excel application from .NET. You create an ExcelApp object, do what you want with it and dispose of in the end.
The problem is I don't have a clue of how to do this.
How should I expose the WPF app's API to my add-on?
Could it be possible to have the WPF app responsive and controlled from the Revit add-on at the same time? (user can still click the abort button, the indeterminate progress bar doesn't freeze)
The First thing to know is about interacting between two processes. there are some Standard approaches:
Interacting through Socket (Socket Programming)
Using Named PipeLines (Useful when your messages aren't so long)
There are some other predefined Libraries based on above techniques. Using a FileSystem Based method is not a reliable way to proof the outputs.
This was a part of your solution. The next step is to use Threading in your WPF application. I'm not familiar to Revit and I don't know how it works.
UI freezing is normal in a long running process. because UI is busy and it can't answer your requests (e.g Mouse Move, Click, ...). So using a Thread you can put your long running process into a separate place and wait for the response at the end of it.
There is a problem while using a Thread. Because you left your UI and started your long running process on a separate Thread, you can't directly access to your ProgressBar. In this situations you have to use ThreadDispacher. It's not a terrifying concept, it just a three line of codes that will adds to your callings.
for example:
Dispatcher.Invoke(() =>
{
ProgressBar.Value++;
});
Search for a Library to doing your IPC (Inter Process Communication) to get the result faster (or you can learn about above techniques to do it by your means) and next add a simple thread to your WPF application so you be able to Start, Pause and resume the running job based on the situation.

Possible to have controls in seperate GUI threads in one wpf window?

I'm creating a wpf application which reads sensor data from a webserver.
I then plot these data in graphs as I receive them. The data is sent several times a second.
My problem is that I have about 6 graphs I am plotting in the same window.
And it's lagging and updating unevenly, so I guess that is because they are all trying to update the same GUI thread at the same time.
How can I improve this? Can I have the graphs in different GUI threads in the same window, or is there another way to handle this?

WPF WebBrowser not updating when WinForms Chart is updated in WindowsFormsHost control

I have a WPF application with two windows. One window contains a WebBrowser control. The other window contains a WindowsFormsHost which hosts a WinForms Chart control for drawing a line chart. I tried with charting provided by WPF Toolkit, but the memory consumption is increasing. I am displaying a local HTML file with javascript to show a location on Google Map. The location is updated every 100 ms. Along with the location, some other data is received which I have to display on the Line Chart.
While testing, I have observed that the graph and browser both are updating well simulataneously with 500 ms interval. But when the frequency is changed to 100 ms, the browser stops updating. It is also observed that if data plotting on the chart is stopped, the browser tiles load back again and location is updating.
Any hint as to what the problem might be??
This sounds like a classic example of either a very busy main thread (UI thread) that is updating the chart is starving out main thread updates to the web browser control. Or if you have separate threads, other than the main thread, updating the chart and the web browser, again the I/O latency updating the chart is short compared to the I/O latency updating the web browser and therefore the chart update thread is starving out the web browser updates. Even if the web browser updates and the chart updates are sourced from separate threads, other than the UI thread, one thread can starve out the other. There too many ways to fix this to list here. You just have to make sure the threads doing the updates to the chart and web browser control have an balanced/equal chance to get a time slice to do their thing.

How do I make a WPF/MVVM application do background processing before displaying a window?

I'm fairly new to WPF & MVVM. I've created a couple standard simple WPF/MVVM applications that show a startup screen and do processing, including displaying other user controls, based on commands within that main window.
But now I want to make a WPF/MVVM monitoring/input-gathering application that starts up without displaying a window, loops through checking the system state until conditions necessitate the window's display, and only THEN displays a window, then processes the user input and goes back to looping. The user wouldn't be waiting for this window, because it's only shown when there's something that needs the user's attention. It would run in the background "forever", only showing itself when needed.
I see that I can make my own Main() method, but I still can't figure out the best way to keep it in MVVM, yet only display the window as needed within a larger loop.
Thanks!
EDIT - we finally did the sane thing and made two different processes, one to do the monitoring and one to do the WPFing. Thanks all!
A Windows Service seems to be the best way to do the monitoring. As soon as user interaction is needed you could signal the rest of the 'world' that something has occured.
A WPF client could pick up the signal and show a UI. The WPF client could be hidden by using a NotifyICon.
MVVM would only be appropriate in the WPF Client. The model contains the status that is monitored, the viewmodel turns this into a model of the view and the view displays the information.
The signal could be a Mutex that is set by the service and tested by the WPF client. Communication between the service and the client could be implemented by using WCF.

Winforms WPF interop performance

My project requires a background thread to initiate the creation of a WPF control hosted in a Winform. The creation of said control must be performed on the foreground thread, which is very costly and causes the UI to hang for 1 to 2.5 seconds (depending on whether this is the first time the control is created).
Are there any pre creation optimizations that can be done from a background thread to reduce the amount of work done by the UI thread?
I assume you use the ElementHost control to host the Wpf control in the winforms app? I think the overhead you're seeing is really necessary, as the device context the wpf elements are rendered on is marshalled to the winforms app and isn't living in a normal wpf application. My experience is that when you open a form with ElementHost on it, the second time is much faster, but of course it depends on what you're doing when it opens.

Categories