We have a very complex software primarily written using .NET WinForms in C#. Many people have contributed to it. One such contribution was the addition of a Windows Presentation Foundation (WPF) control hosted in Win Forms. The said control is considered a common control and used in many places in the application.
Everything was working fine till a few days ago when we started seeing inordinate delay in launching the application. The application used to launch in less than 5 minutes, but now takes 20 minutes to launch.
We have been analyzing the situation but have found it very hard to pin down the real issue. We have seen that our misbehaving common control that is used at multiple places, eventually calls the following framework functions:
The time taken by the system functions to perform their duties is shown in the picture above. The system functions take around 1.5 minutes each time the common control is initialized. We use the common control at least 8 times in our application. So, a total of 12 minutes.
Has anyone else seen such issues with WPF controls hosted on WinForms?
Any help would be appreciated.
EDIT:
There is an issue with C# Dictionary we use. Getting rid of it by using a List<> solves the delay issue. Microsoft has reproduced the issue at their end. They are working on it.
Maybe, our application took C# Dictionary to the edge ;)
Thank you all for providing your inputs.
This is likely to be the Initialization of the WPF control rather than something to do with the ElementHost or the fact that it's hosted within WinForms.
Without seeing the code for the WPF UserControl its hard to tell you what that might be but I would say that the interop of WPF / WinForms is certainly a red herring.
You can try using the Ngen:
The Native Image Generator (Ngen.exe)is a tool that improves the performance of managed applications. Ngen.exe creates native images, which are files containing compiled processor-specific machine code, and installs them into the native image cache on the local computer. The runtime can use native images from the cache instead of using the just-in-time (JIT) compiler to compile the original assembly.
If the assemblies of project will be compiled with help of Ngen, there is no need to run every time JIT-compiler before starting application and loading metadata of using assemblies.
Ngen will find all of the static dependence of the main assembly and compile them all in a low-level images. These images will be stored in cache of assemblies (GAC), thereby it is possible to reduce application load time.
Related
I've written an application in C# .NET with the WinForms UI toolkit. I'm attempting to provide Windows executables, but so far they simply don't work for anyone but me.
I'm creating the release packages by building the EXE and DLLs in Visual Studio 2017, copying them into one place, and putting that into a .zip archive. I'm not doing the fancy one-click publishing stuff.
The project is available on github (https://github.com/fadden/6502bench). The first person to try it got "<program> has stopped working" on Win7 (see issue). The second person was using Win10 Pro, and extracted some details from the event log that show it crashing in a system DLL (see issue). Both of them have the latest .NET framework installed.
I haven't worked with C# .NET outside Unity, so I'm a bit out of my depth. It's entirely possible I've skipped an "obvious" step, or am doing things wrong.
Update: answering some of the comments:
it's pure C#, no native or unsafe code
both people reporting problems confirmed that that latest .NET framework is installed (4.7.2)
the program doesn't seem to be starting at all, so I'm not sure what the app could be doing wrong as far as local paths go
the specific errors, including screen shots and log messages, are included in the issues linked above
the full source code, with the VS solution and projects, is up on github
The sense I'm getting from the comments is that what I'm doing isn't fundamentally wrong, so there's some devil in the details.
I downloaded the source, and debugged.
I received a StackOverFlowException on the following 2 lines of code.
ProjectView.cs
line 3545 : symbolListView.Columns[2].Width = lastWidth;
line 3719 : referencesListView.Columns[2].Width = lastWidth;
What is going on is you are handling the ColumnWidthChanged event on ListView components, and modifying the column width. This modification fires the event again, which is causing an infinite loop, and a subsequent StackOverflowException.
But why? I'll take a swing at an answer. You may have hard coded some values that line up with the DPI and resolution of your monitor. When the ListView instantiates on your machine, it doesn't have to 'redraw' the column with and does not fire the event, but for anyone else that doesn't have the same resolution and DPI, the event fires and causes the loop. I could be wrong, but sounds plausible to me.
I need some help in Making a slideshow type application in WPF. Problem is, Image that needs to be used in this application are .gif, for which i think so we dont have any control in WPF.
Does any one have any idea of how to play those images without impacting any kind of performance? Also the machine in which i need to use this application is windows XP, that means the we can only use up to .net 4.0.
What I have tried:
I have tried many examples find over this page, but the memory it consumes is too high as i need to change image more often.
Dll's that i have tried are
wpfanimatedgif:- It has some serious memory leak issues.
also i have tried
XamlAnimatedGif:- it works fine while running on .net 4.5 machine. but was unable to display any image while on .net 4.0 machine.
I'm creating a C#.Net application which I want to be able to compile for "All CPUs". I also want to include a specific ActiveX control in the UI of this app, but the ActiveX control I'm trying to use does not support 32 bit. Is there some trick or work around I can use to use get this control to work?
What about embedding the ActiveX control in a Web-browser control? Would this even work?
You have to run the ActiveX control in a separate 32-bit process. That's going to be difficult, it would have its own window that isn't going to be part of the UI of your 64-bit process. Although it is expressly forbidden by the SDK docs, you can try to take advantage of the Windows 3 appcompat built into the SetParent() API function. It might work.
You'll have lots of additional trouble, communicating between processes is tricky enough (you'll need Remoting or WCF), the hard part is dealing with exceptions. One process bombing with the other one surviving and never noticing that something is wrong is not going to be pretty.
Perhaps the Platform Target option starts sounding attractive?
You can't load 32 bit components in a 64 bit application, but you can wrap the component in its own process and use IPC to leverage the features of the component. Of course this may not be feasible depending on the actual component.
Sometimes I create some quick personal projects using C# with Windows Forms or WPF. I have noticed that managed applications can take 2x or 3x times longer to start compared with native applications.
I have written a "Quick Notes" application, however it isn't very "quick". :-(
What are some techniques to speed up the initialization of Windows Forms/WPF applications?
Check out NGen
Also, if you are loading lots of data on load, move it to another thread and show an indicator or something (while it's loading) so at least the form pops up quickly, even if it takes a little longer for the actual data to load.
.NET 3.5 SP1 does tend to make start up a little quicker. Also see a series of blog posts on putting up a splash screen (in native C++) while starting the WPF application at the Logos Blog.
.NET 3.5 SP1 also now includes the ability to create a fast SplashScreen without using C++
You might also want to consider moving processing off to worker threads. When your app starts load the root UI, but not the data - rather load the data async (and create pad windows etc. as each data item comes in).
.NET applications made for .NET 3.0 or later work much better on newer versions of Windows, Windows Vista, Windows 7, etc. I think in a few years time the difference between managed and unmanaged code in terms of performance will unnoticeable.
I am responsible for the User Interface of an application written completely in Visual C++ using MFC and some third-part controls. I would like to use C# (WinForms or even better WPF) to improve the application look&feel.
I would like some advices about how to do it. Links, articles, examples...
Right now the user interface is isolated in a single project and I don't want to compile the whole module with CLR. So how do I have to manage that from the architectural point of view?
I have already looked at the Internet for the subject and read MSDN information. I would like more detailed information...is it convinient? pros/cons? have you used this approach successfully in a "big" application?
I don't want to compile the whole ui project with CLR...can I just have all the .NET code in a isolated project and call it from the ui project? what's the best way to do it?
Thanks in advance.
A good starting point is the Win32 and WPF interop page on MSDN.
I found this codeproject article gave a good introduction to the subject of mixing mfc / winforms code.
When faced with the same problem, I made an ActiveX control in C# and used it in my MFC app. The folks at MS took out support for building ActiveX controls with .NET, but it's still possible to do so with a plain Jane COM class which has a custom [ComRegisterFunction()] and [ComUnregisterFunction].
Although MS would like to tell us that the /clr flag will solve our problems, it measurably slowed down my large MFC app.