Preloading Assemblies - c#

At work we use DevExpress for the user interface. The first time a form employing a DevExpress control is opened there's a long pause (sometimes 15-20 sec on some clients). In Visual Studio i can see that tons of assemblies are being loaded during that phase. Is there a way to preload that assemblies into the AppDomain in the background on a thread that is spawned for example before the login screen pops up?

Another choice is to force the JIT to load the assemblies asynchronious instead of doing it by hand. The trick is to simply call the constructor of the control, so the Jit knows that it has to start compiling that particular code path. Usually that forces it to load all dependant assemblies. Just make sure to surround the call of the constructor by a try catch.
An example of how to do that at loadtime:
static class Program
{
/// <summary>
/// The main entry point for the application.
/// </summary>
[STAThread]
static void Main()
{
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
PreJitControls();
Application.Run(new Form1());
}
private static void PreJitControls()
{
ThreadPool.QueueUserWorkItem((t) =>
{
Thread.Sleep(1000); // Or whatever reasonable amount of time
try
{
AssemblyPullingControl1 c = new AssemblyPullingControl1();
}
catch (Exception) { }
try
{
AssemblyPullingControl2 c = new AssemblyPullingControl2();
}
catch (Exception) { }
});
}
}
But you could also do something similar in the constructor of the login form, if that is a better time to do the pre-loading. Just move the PreJitControls method to the login form and call it from the constructor.

This will however force your users to always take that hit on start up.
In general this is a bad idea (if you have the hit at least defer it till you really need it). A case where it might help is to trigger the load if there is a strong chance that they are going to use the functionality in the near future but the system is otherwise idle. This can be very hard to do accurately though.
You might see whether any of the loaded assemblies are under your control and in the GAC. If so you could ngen them which may have a significant effect on the start up time of this aspect of your UI.

I'm not sure, but I am guessing that not the actual loading of the assemblies is the timeconsuming part - but probably the JIT compiling of the code path. Maybe you want to look at ngen. could be that it makes the performance problem go away. but be sure to understand the implications of that tool.
Links:
- http://msdn.microsoft.com/en-us/library/6t9t5wcf.aspx
- http://msdn.microsoft.com/en-us/magazine/cc163610.aspx

have a look at the Assembly.Load methods.
Gero

If you are trying to get your assemblies faster, why not have a look at NGEN for your code. Pre JIT everything in the background. This has pro's and con's though depending on what your app is doing.

Related

c# while loop prevents form from loading

I am making a "Main()" function in a WindowsForms Application in C#. I have been following a book on Game programming in C#. When I run the examples everything works, but when I try to make my own version nothing works.
Here's the Main() function:
public void Main()
{
while (!gameOver)
{
// Non timed code:
int ticks = Environment.TickCount;
if (ticks > lastTick + 16)
{
lastTick = ticks;
//Timed (60FPS) code here:
Application.DoEvents();
}
}
}
When I put this inside the "Form1_Load" function the form does not even show when I start the program, while not giving any errors or warnings (the same thing is done in the examples, which runs). If I move my "Main()" to for example "MouseClick" and the form shows and when I click is the function starts running as it should.
I am really out of ideas as to why this happens. Am I missing something really obvious here?
A form's Load event is not exactly the best place to start a game-loop. There are two basic reasons that Load will be fired. The "good" way is when it happens in response to the Show() call, normally present in the Program.Main() method. Your game-loop will work.
The "bad" way is when code in your form constructor requires the form's Handle property to be valid. That forces Winforms to create the native window and that triggers Load. That still usually comes to a good end, the odds get lower the more convoluted it gets.
That will go wrong in your case since the Load event handler doesn't return. Which means that the constructor cannot complete. Which means that the window cannot become visible. Which means that "gameOver" can never become true. Game over. You diagnose this with the debugger, set a breakpoint on the Load event handler and look at the Call Stack window. With the expectation that you'll see the statement in the constructor that caused the problem.
Last but not least, be very wary of this failure mode.
The real fix is to put this code in the right place. Which is in the Program.Main() method. Roughly:
[STAThread]
static void Main() {
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
// Application.Run(new Form1()); Not this anymore
var window = new Form1();
window.Show();
// Your game loop here
//...
}
You could try putting the loop logic in a static void method and executing it on a thread
that way it will go about its merry way and the form will go ahead and load

Window disappears too fast for Coded UI Test

In a program that I'm testing with Coded UI Tests, I've got a window that opens for only a second or so, and I want to verify that this window is opening.
Is there a way to freeze the program, or make it run slow so that the test is able to find that window?
As I already mentioned in my comment there isn't much (perhaps nothing) you can do by the CodedUi Test to catch the window, since this functionality is built into the application.
My suggestion is to make this property configurable. Some of the properties in the applications under test need to be configurable so it can be tested. Consider the following requirements:
The service is restarting every month.
The user is deleted after one year of inactivity.
How would you test them? Will you wait a month or a year to go by? Those kind of parameters have to be available for the Qa team, otherwise they cannot be tested. I know that with this approach you have to do changes to your app's code and build but I think is the only way to solve it.
How about adding a Thread.Sleep(100);
http://msdn.microsoft.com/en-us/library/d00bd51t
From what I understand, the best approach is to break up your tasks as small as possible. So for a UI test I did that opens a shortcut on my toolbar, clicks login on a popup within, then clicks a tab in the application, the code looks like this:
namespace CodedUITestProject1
{
/// <summary>
/// Summary description for CodedUITest1
/// </summary>
[CodedUITest]
public class CodedUITest1
{
public CodedUITest1()
{
}
[TestMethod]
public void CodedUITestMethod1()
{
// To generate code for this test, select "Generate Code for Coded UI Test" from the shortcut menu and select one of the menu items.
// For more information on generated code, see http://go.microsoft.com/fwlink/?LinkId=179463
this.UIMap.OpenWindow();
this.UIMap.ClickLogin();
this.UIMap.ClickDevelopment();
}
//snip
}
So then in the ClickDevelopment() method, I know that the program should be visible, so rather than just dive right into the method actions, I can throw a Thread.Sleep() to make it visible for a little while longer.
public void ClickDevelopment()
{
Thread.Sleep(10000);
#region Variable Declarations
WinClient uIDevelopmentClient = this.UIQualityTrack30Window.UIItemWindow.UIQualityTrack30Client.UIDevelopmentClient;
#endregion
// Click 'Development' client
Mouse.Click(uIDevelopmentClient, new Point(39, 52));
}
Use Playback.Wait(2000) instead of Thread.Sleep(2000);
Best possible method is to add polling mechanism.
As soon as you perform the action which will open the window, call a function which will keep checking whether the window appeared for say, 1 min or so.
Be sure to call this function as soon as you perform action.
So even if the window stays for 500 millisecond, the info will be captured.
We have done similar thing in our project.

Using WUAPI to quietly install updates in C#

I'm trying to create a program that will handle updates silently. I am using the wuapilib.dll, which comes with a number of classes (c#). My first revision of the program was as follows (ignore typo problems - its on another computer without internet access so i'm typing it by hand):
IUpdateSession mySess = new UpdateSession();
IUpdateSearcher mySear = mySess.CreateUpdateSearcher();
ISearchResult myRes = mySear.Search("Type='Software'");
IUpdateDownloader myDown = mySess.CreateUpdateDownloader();
IUpdateInstaller myInst = mySess.CreateUpdateInstaller();
myDown.Updates = myRes.Updates;
myDown.Download();
myInst.Updates = myRes.Updates;
myInst.Install();
Ignore the case where an update is already downloaded or installed, I'm omitting the logic above. My problem is that IUpdateInstaller doesn't allow you to force a quiet install - a number of updates require that a user click a confirmation box. The IUpdateInstaller2 class does (I got that from the second post down here), but for the life of me I can't find a way to get an IUpdateInstaller2 object. Nothing seems to return one, and Microsoft's documentation doesn't contain any example code. Extensive googling returned nothing of use.
I think I'm really close - the functionality is there, I just can't quite access it.
Thanks for your help.
I checked that (or rather, I think i did - wasn't too clear on getting it to work), and it looks like the CreateUpdateInstaller only returns an IUpdateInstaller, nothing else.
However, I found code (on a chinese website, interestingly enough) that just directly cast the IUpdateInstaller to an IUpdateInstalelr2, which has solved my problems.
Thanks for the help
I have posted in another Question my app to, search, download and then install Windows updates.
See: C# and WUAPI: BeginDownload function
you can easily change the:
static class Program
{
/// <summary>
/// The main entry point for the application.
/// </summary>
[STAThread]
static void Main()
{
Application.SetCompatibleTextRenderingDefault(false);
Application.EnableVisualStyles();
Thread thread = new Thread(() =>
{
Form1 form1 = new Form1();
form1.Visible = false;
form1.ShowInTaskbar = false;
Application.Run(form1);
});
thread.SetApartmentState(ApartmentState.STA);
thread.Start();
}
}
then handle
Application.Close();
after the events have done their thing. For example, if no Updates have been found, then close the app. I use the async properties of the interfaces so it can do what it needs to async.
Hope this helps.
I also searched a long time for it.
You just need to cast it
IUpdateInstaller2 installer = new UpdateInstaller();
According to Microsoft documentation there are also version 3 and 4 available. But this must be an error. The functions of version 3 are available also in IUpdateInstaller2 and the functions from version 4 I never found somewhere.

How to stop a .NET application from loading if certain criteria aren't met

I need certain criteria to be met, a particular folder needs to be present on the c drive, before this app should load. How, during the load process, can I stop/quit the application.
I already have ascertained if the folder exists. In old VB projects you would just use 'Unload Me' but that isn't in C#. I tried Application.Exit() but that doesn't work under these circumstances and the app still loads, how do I stop it?
Open up Program.cs. In there you'll find you Main() method.
In there, put something like:
if (FolderDoesNotExist())
return ERROR_FOLDER_NOT_EXIST;
(replacing those symbolic names with other stuff as appropriate).
I would create an initialization function that would be the first item to be called from Main(). Depending on your output and how long your initialization takes you can even use a splash window to inform the user about progress. Once all initialization is completed, you can decide if you start the app or not.
// In the main initialization of the main form (in XXX.Designer.cs file InitializeComponent(), for example)
this.Load += new System.EventHandler(this.CheckProcesses);
// The CheckProcess method
private void CheckProcesses(object sender, EventArgs e)
{
try { if (SomethingIsWrongWithThatFolder()) this.Close(); }
catch { }
}
// This will shut the process of your app before the UI actually loads. So, your user doesn't see anything at all

C# Error on Close

When I close my C# application, I am getting the a windows sound that indicates an error. However, when I debug through the close process, I get all the way back up into the Program class...
It gets past Application.Run(..), exits the static void Main() function, and then makes the error noise.
Other than the noise there is nothing indicative of an error. I don't even know where to begin looking! Any ideas?
One thing that you could to in order to maybe get some information is to hook up event listeners for the AppDomain.UnhandledException and Application.ThreadException events. It's a long shot, but may provide some info. You could add the following in the beginning of the Main function to set them up, and have them show any exception info in a message box:
static void Main()
{
AppDomain.CurrentDomain.UnhandledException += new UnhandledExceptionEventHandler(delegate(object sender, UnhandledExceptionEventArgs e)
{
MessageBox.Show(e.ExceptionObject.ToString());
});
Application.ThreadException += new ThreadExceptionEventHandler(delegate(object sender, ThreadExceptionEventArgs e)
{
MessageBox.Show(e.Exception.ToString());
});
// run your app
}
It only happens when you close your app or does it happen when you close any app?
My first thought would be that someone changed your windows sound scheme and set the close program sound to mess with you :).
Something is going wrong in the cleanup, that could be very hard to find. There are two ways to attack this:
Enhance the chances of detecting it while you're still in control (in Main) by wrapping everything in your Main in a try/catch and add some code after the Application.Run to get as much of the cleanup going as possible. A few things I can think of:
GC.Collect();
GC.WaitForPendingFinalizers();
Thread.Sleep(1000);
GC.Collect();
GC.WaitForPendingFinalizers();
Collect at least 2 times, maybe more. In the same spirit, add a few Application.DoEvents() in the OnClosing of the MainForm.
The other approach is more dependent on your code, to take a stab in the dark: look for all static fields/properties you can set to null and Disposable objects you can Dispose deterministically on Exit.
And all this in combination with Fredrik Mörks suggestion for the UnhandledException event.
Do you have any code that raises custom events? Could these processes still be running when the app tries to close in real-time?
Do you have any custom Dispose code that could be running at time of close?

Categories