Go Back

Can AppDomains be used to speed up start up time in synergy.net applications?

I have a synergy.net WPF application which is getting slower and slower to load as more functionality is added. Ity runs fine once loaded.  My client wants to add a lot more functionality. It currently takes over a minute to load.

Is it possible to isolate coding contained in assemblies say for "Sales Orders" so that it is only loaded if the user navigates to that visual state and loads the views and associated viewmodels in that assembly ?

If it is, I have some common assemblies for data and file IO classes. Can they be loaded at the start and shared by each App Domain, or would I need to load a local copy oif this assembly in each AppDomain.

Assuming this is possible, what would the startup coding look like for the application, and how would I load an assembly before navigating to a visual state which needed it?

Ideally I want to load my application to the initial menu in under 10 seconds and I don't mind further 5 to 10 second delays as they load different parts of the application.

I just have no idea if this is possible of how to go about it

I'm happy for examples in C# which I can translate into the ysnergy.net world
 

16 Answers
0   | Posted by Gordon Ireland to Synergy .NET on 1/6/2021 12:49 PM
Steve Ives
Hi Gordon,

Some input from me and others:

No, AppDomains app domains would likely make things slower and would make the task of fixing the issues harder.

It's difficult to offer good advice because what you're talking about is pretty complex, and there could be many different things that are contributing to your perceived performance issues. But in general, for something like a WPF application, things that would make an app start faster would include:
  1. Reducing the number of global and common variables that are used.
  2. Reducing the size and complexity of XAML resource dictionaries.
  3. Separating application functionality (Models, ViewModels, and other supporting code) into different assemblies.
  4. Splitting XAML views into different assemblies that are actually separate from each other (i.e. carefully planning what XAML windows and user controls are in each assembly). The more granular the better.
This final point is probably where you can have the most impact on startup time because an assembly won't be loaded until something in the assembly is actually required, but then everything in the assembly is loaded. If you look in the install folder for many large-scale desktop apps, you will typically find a pretty small .exe file and a whole bunch of small .dll files.

Good luck!

 

1/8/2021 12:26 AM   0  
Gordon Ireland
Here's an idea I would welcome some input on.

1.  Split the application down separate .EXEs which all reference the same base classes and data and file class project

Have a menu application which just loads the bare minimum and allows them to pick "File Maintenance", "Sales Orders", Sales Ledger", "Purchase Ledger" etc.

Then have separate EXEs for each of these which only have the assemblies they need, and a reference to the base and data and file IO assembles

If they select an option it uses xcall shell to run the required EXE.

This would allow them to have the menu and a number of modules open at the same time 

What are the views for or against this idea ?

My aim is to get to the main menu  screen in under 10 seconds, and then have a max of 10 seconds to load any module from there, regardless  of how many modules I have



 

1/9/2021 12:30 PM   0  
Steve Ives
It's not necessary to split into multiple EXE's in most cases, a single EXE and LOTS of small class library assemblies that can be dynamically loaded as necessary is preferable in most cases, but that's your call, of course.

The modern term for what you are describing as a "menu application" is an Application Shell (sometimes referred to as a Navigation Shell). The idea is that the shell is the "EXE" that provides things like user authentication, authorization, navigation menus, color schemes, layout, recently used lists, user favorites, messaging (toast messages), security, etc. And the small and light shell app, that ideally starts very quickly, then dynamically loads "content" (applications) as needed.

We consider this to be total "best practice" today, regardless of whether your environment is desktop or browser-based. Several customers have already gone down this path, and we're working with others right now who intend to do the same thing.

Some of the first to do this, and do it right, were our friends over at TurnKey and Rural Computers, both of which worked with our partner Billy Hollis from a UX design point of view. Here are some videos re. their experiences:

1/13/2021 1:04 AM   0  
Gordon Ireland
That sounds EXACTLY like what I want.

My understandaing of WPF applications are that they load the initial window and the XAML defines a number of visual states.  Most of these visual states have their own sets of visual states, often with their own viewmodel.

Each view model and associated views and visual states are in separate projects / assemblies

My using debug it seems that starting up the application loads this entire visual tree and instantiates each view model, including opening files and building lists in the View model constructor    

How do I set up by application shell so that it only loads an assembly if I click a button and switch to a visual state which needs that assembly, rather than loading EVERYTHING at the start  ?    That would be the key to what I need.

I will check out the videos to see if that is covered



 

1/14/2021 9:31 AM   0  
Gordon Ireland
I have checked the videos (again - I was there at the conferences).

In both cases Billy Hollis provided the Application Shell.  The application shell calls xaml views and view models (I assume) and these communicate with with a Harmony Core type back end, where all the data objects, data  access and business logic resides.

My application is structured into the same components  but all runs in the same EXE, ie, the data access is not in a separate execuatable accessed via web services, and I need the data objects in my view models, so these classes need to be in my front end eapp even if I did split it.

I don't think loading the assembly with my file and data objects and custom back end logic is my issue.   I have a similar assembly in their low level windows synergy.net application, and that loads in a few seconds.

The issue is that the XAML visual states are forcing all assemblies to be loaded up front.

My application has an EXE with 50 DLLs which is 94MB in size in the software folder

Conceptually I would like a lightweight menu which handles company selection, user and role verification and set up, themes and main menu presentation

I only want to load the  sales order entry assembly with its views, visual states and view models if they pick it from the menu.

I only wanty the initial vie wand visual state to put a button on the screen an d nothing more.

i then want to be able to do "something" which says load an assembly which contains views, visual states and view models, and then move to a visual state within it.

Is that possible?



 

1/14/2021 4:36 PM   0  
Steve Ives
It seems like you have answered your own question with "The issue is that the XAML visual states are forcing all assemblies to be loaded up-front."

That's what you have to fix. My guess is that this issue, as well as causing perf issues in your current "monolithic" app will also be a barrier to you breaking down the app into multiple executables. It's the same problem, you'd have to package in the executable everything that is needed by the functionality that the executable presents, and only what is needed. It's the exact same challenge. In really simple terms an executable and an assembly are the same. An executable IS an assembly, it just has a different file extension and an entry point!

By the way, please don't be offended by me describing your shiny new WPD app as monolithic. I'm sure it is very modern, and pretty, and works great ... once loaded. But it is effectively a monolithic architecture in that right now it's current architecture results in an "all or nothing" situation. It sounds like you have done the right thing by breaking the code up into small pieces, but that doesn't help if the organization of your UI causes all of those pieces to be required as soon as the application is launched,

You need to figure out how to re-work the view states such that they are function-specific, and package them in an assembly with the rest of the code for that function.

As you know I know enough about WPF to be "dangerous", but I'm no expert. But there are others that read these forums that do have more expertise, and there are some that are really good at addressing .NET perf issues. Perhaps it would help if you try to break down for us why/how your visual states are working the way they do, the way that causes the load issues?

To do so might require you to post some actual examples, but this forum has a hard limit on the size of each post, and it's not that big! If you want to post some code for review and suggestions, then using GitHub Gists is a good way to do that. Here is an example:

Steves Gist Example (github.com)
 

1/14/2021 7:12 PM   0  
Gordon Ireland
I found this by googling.  It looks like there a framework for doing this - Prism Unity.

I assume Billy Hollis uses something like this - does anyone know ?

Does anyone have any experience of working with this or know of any other options to consider ?

 

Prism is a framework for building loosely coupled, maintainable, and testable XAML applications in WPF, and Xamarin Forms. Separate releases are available for each platform and those will be developed on independent timelines. Prism provides an implementation of a collection of design patterns that are helpful in writing well-structured and maintainable XAML applications, including MVVM, dependency injection, commands, EventAggregator, and others. Prism's core functionality is a shared code base in a Cross Compiled .NET Standard and .NET 4.5/4.8 Library. Those things that need to be platform specific are implemented in the respective libraries for the target platform. Prism also provides great integration of these patterns with the target platform. For example, Prism for Xamarin Forms allows you to use an abstraction for navigation that is unit testable, but that layers on top of the platform concepts and APIs for navigation so that you can fully leverage what the platform itself has to offer, but done in the MVVM way.

Prism 8 is a fully open source version of the Prism guidance originally produced by Microsoft patterns & practices. The core team members were all part of the P&P team that developed Prism 1 through 5, and the effort has now been turned over to the open source community to keep it alive and thriving to support the .NET community. There are thousands of companies who have adopted previous versions of Prism for WPF, Silverlight, and Windows Runtime, and we hope they will continue to move along with us as we continue to evolve and enhance the framework to keep pace with current platform capabilities and requirements.

At the current time, Prism supports WPF, Xamarin Forms and UNO. We have no plans to create new versions of the library for Silverlight, Windows 8/8.1/WP8.1 or for UWP. For those you can still use the previous releases from Microsoft p&p here and here or previous releases of this library in the GitHub Repo.


1/14/2021 7:48 PM   0  
Gordon Ireland
I have it sorted.  My application now loads and displays the menu in under 5 seconds

It dynamically loads user controls via reflection as it needs them

I have a single user control which allows me to pass the user control name and assembly, and where I called it from so it can return and manage visual states correctly.

Feels like I now have my own app shell.

It handles user verification, role based security, theme selection and menu selection, and the loading and unloading of the user controls relating to the menu options selected.

It uses IG controls and themes, so it looks good

1/20/2021 5:48 PM   0  
Steve Ives
Good news, glad you’re happy with the app now. And effectively yes, you have an App Shell.

sorry I didn’t get back to you about Prism. My understanding is it’s the 1000 pound gorilla of MVVM frameworks, probably does pretty much what you use Symphony for.

1/20/2021 6:30 PM   0  
Gordon Ireland
I didn't use Prism.

I found other examples but they ignored visual states, but I figured out how to load controls, remove controls, and keep track of visual states etc via messaging in an MVVM friendly manner
 

1/20/2021 6:33 PM   0  
Gordon Ireland
I added a final bit of polishing.  I found I was able to cache user controls which have already been loaded so if they are selected again they load instantly.

The users love the new Application Shell approach - so much faster.  2 to 3 seconds to load the menu, 5 to 6 seconds to load a menu option for the first time - instant for subsequent loads of the same option

And on the development side I don't need a separate visual state in my menus for every menu option - I removed a few thousand lines of  visual state coding from my menus

1/29/2021 11:16 AM   0  
Steve Ives
Sounds like a job well done, Gordon. Congratulations. We spend so much time building functionality that it is easy to, well, not lose sight of other things, like performance, but sometimes put them to the back of our minds. Your story is proof not only that performance is important, but that there are things that can be done to improve perf in existing applications. And changes like that will always make users happy!

1/29/2021 5:57 PM   0  
Brent Parish
Hey Gordon, great job on speeding up your app! Would you be able to post(on github or similar) a small sample project demonstrating this approach? As this is something I (and I am sure others) have hit in the past. 

2/11/2021 10:27 PM   0  
Gordon Ireland
Are you taking about a n MVVM WPF application in synergy.net or C# ?

If this is interest in this I'm sure I could strip it down to a simple example.

Let me know who would be interested in this

 

2/11/2021 10:31 PM   0  
Brent Parish
WPF in C#, I'm just looking for a bare minimum example with just a window with a button, that when clicked loads a control on demand.

2/11/2021 10:40 PM   0  
Gordon Ireland
Hi Brent.  My application is written in synergy.net and uses Symphony Framework classes to handle things such as messaging between viewmodels, mainly for an exit button in a user control to tell the menu that it wants to exit from the visual state that called it.

Having said that I am familiar with C# and the reflection solution, like every other example on the web, was in C#.

Would it be possible for you to write the basic C# app with a window, a button, and a user control with an exit button and an associated viewmodel and I will apply my solution to it ?

I reckon it would be a lot quicker for you to produce the example than for me

WHat do you think ?

Gordon
 

2/12/2021 9:30 AM   0  
Please log in to comment or answer this question.