Serge's Technology View

Talk about Technologies, Software Architecture and Management

Archive for the ‘Fun stuff with C#’ Category

Crystal Reports 2008 and ASP.Net : speed up the first session

Did you ever noticed that after restart of the IIS ASP.Net page which has Crystal Reports Viewer would take much longer to come up?

Some of it is expected since on initial start up, a number of Crystal assemblies and objects need to be created and this does take time.
I want to emphasize that discussion below is related to the first run of any reports. We have to actually restart/reset IIS to see problem again.

Note: There was a question about IIS’ Application Pools recycling which could cause similar effect. Make sure your application pool is set properly.

Setting up a playground

Let’s assume ASP.Net pages were already migrated to use .Net 3.x and look at what happen behind the scene.

Remember that after restart IIS starts from ground up. This means several things in respect to our page content:

  • .Net assemblies need to be preloaded and validated if necessary.
    Since Crystal Reports 2008 comes as .Net 2.0-based core and we may already moved to .Net 3.x, CR2008 Engine and some additional files need to be loaded and validated aside from one which already used by any previously loaded pages.
  • For each session engine would create a cached version of RPT file in temp folder.
  • Some code would have to be brought to the client machine for Viewer to operate properly.
  • Database connection established, data retrieved, processed, paged and sent to the client Viewer.

That about it, now we ready to work with reports. Please notice that after that initial load, any other reports would come up faster. We could even close the browser or use another browser (ex. go from IE to FF) and it would be still faster than the first time, so there is something important about the first step above…

Combing the sand

Let’s try to break the IIS initialization process to get more detailed view.

Since we already had some ASP.Net pages loaded before coming to CR related page, we could disregard .Net core initialization procedure. It is there on IIS side: used and ready.

Ok, next thing is CR engine related stuff. There is some 5Mb of files in crystalreportviewers12 folder to support CR Viewer in ASP.Net and we need to send some of them over the network. In addition to that there is Crystal Reports Engine assemblies which need to be loaded by IIS at the time of the first use. And this is our spot to dig.

If we try and trace what exactly going on we would notice that aside from IIS loading a few dozen assemblies, there is also process associated with trying connect to CRL.VERISIGN.NET.

What is it?

“Problem” is that assemblies are Authenticode signed and therefore need to be verified or it technical terms they need to be checked against Certificate Revocation List (CRL) by Publisher for Code Access Security (CAS).

Default behavior is that they need to be verified by the certificate authority. If certificate is not present on the same machine (I have my doubts that SAP doing anything about that, but I could be wrong), validation need to be done via central repository mentioned above, or if machine does not have network/internet access the .NET thread might timeout waiting to connect.

Yes, by performing strong name signing of assemblies or placing the CA certificate on the same machine issue would be avoided, but it seems not being a case.

Building the castle

Since assemblies are provided by SAP, we cannot remove digital signature and it is a hassle to keep certificates current by obtaining them from CA every time they expire. Let’s concentrate on the Publisher mentioned above and turn it off.

It is all-or-nothing solution since it would require turning off CRC for the entire IIS.

When working with regular .Net apps, it can be done on the app level (assuming we already have fix for .Net 2.0) by adding the following section in <Application>.exe.config

<configuration>
  <runtime>
    <generatePublisherEvidence enabled="false"/>
  </runtime>
</configuration>

This new element described in this MSDN article. Interesting note there (why not to turn it then by default? Oh, security concerns… UAC anyone?):

We recommend that services use the <generatePublisherEvidence> element to improve startup performance. Using this element can also help avoid delays that can cause a time-out and the cancellation of the service startup.

Since there is no such config file for our ASP.Net app (web.config would not work here, because it defines settings that are only AppDomain wide and we need process wide for aspnet_isapi.dll being the hosting environment for the runtime), we would have to turn code access security (CAS) publisher policy off for the entire IIS.
There are two options:

  • Create a file called w3wp.exe.config (for IIS6, or aspnet_wp.exe.config for IIS5). This will affect all .NET based web applications on the system.
  • Or to specify this in machine.config, but then this affects every .NET application on the machine and is not available for override in individual Apps.

Adding the summer cabin

There is one more step which could be taken to improve performance by preloading some of the core assemblies while site visitor is doing something else.
I wouldn’t go into much details here, since it is implementation/application environment specific, but just give a hint:

  • some other place in application, create a background process which would create CR document object, load some not essential report file, retrieve some data and then disapear without the trace. This would allow Crystal Reports Engine being initialized in the background offsetting time needed for the actual CR related page load. Don’t force garbage collection though, this may cancel desired effect.

Results

In some situation I observed 50% to 70% drop in start-up time…
Have fun!

File locks or when garbage collection goes bad

With introduction of garbage collection (System.GC name space) in .Net, life of the Windows programmer become easy – no need to worry about releasing objects, code become simpler, etc.
In “old” time one would need to use Interfaces to achieve similar functionality and it does have some advantage even over GC – immediate garbage collection or release of allocated resources/objects.

When writing code in .Net some of us take many things for granted and not always keep in mind that many operations are performed in the context of the unmanaged code or in the “old way”…

File operations or legacy code wrappers are perfect example.
Just because library is available as managed code, it does not mean that everything has ability to “self-heal”.
For example in code file is open for edit with lock being placed.
If the file in not closed explicitly, it would be a responsibility of the owner process to release the lock at the time of releasing associated resources – when process is destroyed.

With garbage collection, just because we are no longer using/owning the process/object, it does not mean that it has been destroyed immediately after. GC management core will release object when it “feels” fit, therefore introducing latency into the process.

Off course, proper way would be to be more careful within the code and make sure any locks are released in managed and predictable way: Open/Close, Lock/Unlock, … Easy solution, but not always accessible, especially when working with 3rd party libraries.

So instead, we can force GC manager to “collect garbage” in-place with the following small code:

// See code follow up below
System.GC.Collect();
System.GC.WaitForPendingFinalizers();

What does it do?
First call will instruct GC manager to start the process (1), while second (2) will make sure that we wait for process to be completed.

In the case of the file locks, only after GC has released process which placed the lock in the first place, we can manipulate with the file (ex. delete, rename, move).

Assert is your friend… not an end-user’s

As a long time Delphi and C# programmer one become used to some features of the language and may not go deep into “philosophical” thinking about such features. This often happen with Asserts

What is Assert or Assertion?

By its definition Assert:

  • state categorically
  • affirm: to declare or affirm solemnly and formally as true
  • insist: assert to be true
  • In Computing (wiki): “an assert is a predicate (i.e., a true–false statement) placed in a program to indicate that the developer thinks that the predicate is always true at that place”

In general, using assert in the code proven to be useful in many situations because it “checks for a condition and outputs the call stack if the condition is false” and it could help to debug some strange situations in the code.

Assert is your friend

This method is for programmers to use. But what happen often when something is convenient, it started to be used excessively. Why it is happening?

Let’s look at the declaration of Assert in C# (3.x). There are two versions of the Assert(): Debug.Assert() and Trace.Assert(), both in System.Diagnostics namespace.

// Checks for a condition and outputs the call stack
// if the condition is false

[ConditionalAttribute("TRACE")]
public static void Assert(bool condition)

[ConditionalAttribute("TRACE")]
public static void Assert(bool condition, string message)

[ConditionalAttribute("DEBUG")]
public static void Assert(bool condition)

[ConditionalAttribute("DEBUG")]
public static void Assert(bool condition, string message)

As we can see from above code, Assert is to be used for Testing and Debugging and therefore should not be used as a way to present any information to the end-user.

Helping yourself

As useful as it seems, even then Assert infrastructure may not be used to full extend. In the sample declarations above we can see that logic can be invoked with and without providing any additional information.
Imagine how useful is a message “Project raised an Assert in line X” compare to “Project raised an Assert with the Message in line X”.
First option gives you idea where something failed, where second actually tells you what went wrongand where. Let’s use power of the tool-set and provide ourselves with useful information.

Assert is NOT for an end-user

I was asked recently (this seems to be a ongoing discussion) – “Why a programmer should not be using asserts as a regular approach in code conditions validation even when it comes to a production code?”

By default, Assert would show a message box with some information and the current Call Stack. This information, while being helpful to the developer, would not tell much to the user.

With custom TraceListener introduced, message can be hidden from the user and information could be stored, but it is not how it should be used by definition.

If information is expected to be presented to the user in any form, it could be achieved in a form not an exceptional, intended for debugging, situation, but by using regular methods: message box, application log, Windows event log, etc.
Even in the case of component development it is desired to use exceptions (raise/throw) to “bubble” proper message to the error handling layer.

The throw statement is used to signal the occurrence of an anomalous situation (exception) during the program execution.

Assert is a conditional logic

Last, final and probably major concern here is that in Release environment Debug and even Trace functionality would be disabled and therefore, any code/logic which depend on Assert() would be suppressed and all the nice validations became worthless (see declaration above)… and Access Violation errors starting pop up unexpectedly.

.Net and Design Patterns

Evolution has a spiral nature… it is true for any science, process, or development.

Not long time ago Waterfall Model of development prevailed. Very formalized, well described and structured, very structured… and it was “too much” which killed it… like a grandpa, it collected a lot of knowledge and experience, but he was to old and slow to keep up with the grandson… So was WF model - developers wanted something better and simpler, with built-in flexibility and after few iterations we’ve got “Agile model” and “XP programming” emerged. “Spiral” development cycles… “loose” modeling… like with JPEG, developers got “loose compression” of software process definition.

Not that we are loosing quality of the development, but we define the development process with desired level of formality/quality.

Remember in “Pirates of Caribbean” – pirates have “the pirate code”. Not being the law, it was a code of conduct which was helping keep the structure and discipline.

Same for “free spirit” development models, there is the need for some “guidelines” or “rules” everybody can understand and follow if want to achieve structure and efficiency. For the process there is an Agile methodology, and for the code/architecture there are Design Patterns.

First introduced over 30 years ago, term “Patterns” surfaced in software industry several time: originally in 1977, then in 1987 and then finally in 1994.
Since that time and Object Oriented Design becoming main stream in Software Industry it transformed into a common terminology.
It still come in “waves” to one company or another, coming ashore and and then retracting back to the sea of the theories. But with Object Oriented Programming being a mainstream in evolution of software development, Patterns or Design Patterns knowledge become a common base.

Today you hear about it everywhere – “What design pattern did you use?”, “application blocks“, etc.

To think about it, there is nothing new here. As an OO developer you may used it just a minute ago.

So let’s name a few basic one (I am going to use pattern classification presented here or you can refer to The Source – “Design  Patterns” by Gamma/Helm/Johnson/Vlissides (Amazon)):

  • Abstract Factory – allows manage/create instances of several types of classes – generic access.
    A-ha! In .Net the perfect example would be generics and reflection – there you are working with objects without precise knowledge of their type or parameters.
  • Singleton – have you ever created global instance of the class? This is a one example for you.
  • Adapter - we heard it somewhere recently… Aaaa… OleDBDataAdapter… From MSDN: “The OleDbDataAdapter serves as a bridge between a DataSet and data source for retrieving and saving data”
  • Bridge – have you moved from Single/mono-design applications to C/S or created front-end ASP.Net page for your Application Server back-end? Then you have separated interface from implementation of the logic, or used a Bridge pattern.
  • Proxy – Accessing your web-service from your code? Then you have most likely using some sort of Proxy class.

(more…)

Valid XHTML 1.0 Transitional  Valid CSS!