Showing posts with label development. Show all posts
Showing posts with label development. Show all posts

Wednesday, April 21, 2010

Prozess Innovation - notes

ein paar notes zu prozess innovationen....

Standard
- Schlanke und wiederholbare Prozesse
- Prozesse müssen sich internen Bedürfnissen anpassen

Effizänz durch wiederholte Anwendungen
- Mit Wiederholungen steigert sich die Effizienz
- Lernkurve ist sichtbar: Skepsis, Euphorie, Frustration, Beherschung

Payback Effekt



- Breakeven wird schneller erreicht mit effizienten Leistungssteigerungen

Sicherheit / weniger Risiko

- Standardtisiertes vorgehen
- Verlässliche Angaben - Machbarkeit / Kosten / Projektdauer
- Beherschte Prozesse reduzieren das Risiko einzelner Mitarbeiter

Transparanz
- Probleme können frühzeitig erkannt werden
- Vorgesetze können durch Transparenz schnellere Entscheide fällen
- Es kann mehr Eigenverantwortung übernommen werden

Mitarbeiterzufriedenheit
- Industriestandards motivieren Mitarbeiter
- Steigert die Bereitschaft für Veränderungen
- Ausbau der persöhnlichen Fahigkeiten
- Plan - und Steuerbare Mitarbeiterentwicklung
- Bessere Zusammenarbeit im Team
- Steigerung des Marktwertes von Mitarbeitern

Benchmarking
- Priorisierung von Massnahmen

Projekt-Masterplan (Iterationsvorgehen)


Coaching
- Tell me and I forget, teach me and I remember, involve me and I learn (Benjamin Frenkel)

Performance
- Eingespielte Verhaltensweisen bringen Sicherheit und Erfolg

Erfolg = Wissen x Verhalten2

- Nur wenn Mitarbeiter verstehen, und Prozesse vorgelebt werden nehmen Sie den Lernaufwand auf sich

Performance II

Mitarbeiter:

  • Sichere Arbeitsplätze
  • Persöhnliche Weiterbildung
  • Erreichen von Zielvorgaben
  • Interessante Tätigkeiten
  • Teamkultur
  • Annerkennung
  • Eigener Marktwert
  • Moderne Infrastruktur
Akzeptanz Stärken (Transparenz)
  • Frühzeitige und glaubwürdige Informationen von Veränderungen
  • Berücksichtung der Mitarbeiterbedürfnisse und Erwartungen
  • Kommunikation / Feedback
  • Einbezug von Mitarbeitern
  • Erfahrungsaustausch
  • Meilensteine Feiern!!!!
Templates
  • jeder Mitarbeiter muss Informationen in 5 min finden
Metriken

Prozess

  • Periodische geprüfte und auswärtungstand
  • Projektreifegrad
Produkt
  • Anzahl Defekte (pro Woche)
  • Anzahl Use Cases
  • Anzahl der Change Requests
  • Anzahl der Templates
  • Anzahl der Versionen

Monday, April 19, 2010

Development often requires impersonation with Sharepoint (MOSS) 2007


public class Impersonator
{
public string CurrentUser
{
get
{
return this.username;
}
}

public string Domain
{
get
{
return this.domain;
}
}

// private members for holding domain user account credentials
private string username = String.Empty;
private string password = String.Empty;
private string domain = String.Empty;
// this will hold the security context for reverting back to the client after impersonation operations are complete
private WindowsImpersonationContext impersonationContext = null;

// disable instantiation via default constructor
private Impersonator()
{ }

public Impersonator(string username, string domain, string password)
{
// set the properties used for domain user account
this.username = username;
this.domain = domain;
this.password = password;
}

private WindowsIdentity Logon()
{
IntPtr handle = new IntPtr(0);
handle = IntPtr.Zero;

// This stuff required for impersonation
//const int LOGON32_LOGON_NETWORK = 3;
//const int LOGON32_LOGON_SERVICE = 3;
const int LOGON32_PROVIDER_DEFAULT = 0;
const int LOGON32_LOGON_INTERACTIVE = 2;

// attempt to authenticate domain user account
// bool logonSucceeded = LogonUser(this.username, this.domain, this.password, LOGON32_LOGON_NETWORK, LOGON32_PROVIDER_DEFAULT, ref handle);
bool logonSucceeded = LogonUser(this.username, this.domain, this.password, LOGON32_LOGON_INTERACTIVE, LOGON32_PROVIDER_DEFAULT, ref handle);

if (!logonSucceeded)
{
// if the logon failed, get the error code and throw an exception
int errorCode = Marshal.GetLastWin32Error();
throw new Exception("User logon failed. Error Number: " + errorCode);
}

// if logon succeeds, create a WindowsIdentity instance
WindowsIdentity winIdentity = new WindowsIdentity(handle);

// close the open handle to the authenticated account
CloseHandle(handle);

return winIdentity;
}


public void Impersonate()
{
// authenticates the domain user account and begins impersonating it
this.impersonationContext = this.Logon().Impersonate();
}


public void Undo()
{
// rever back to original security context which was store in the WindowsImpersonationContext instance
this.impersonationContext.Undo();
}

[DllImport("advapi32.dll", SetLastError = true)]
private static extern bool LogonUser(string lpszUsername,
string lpszDomain,
string lpszPassword,
int dwLogonType,
int dwLogonProvider,
ref IntPtr phToken);

[DllImport("kernel32.dll", CharSet = CharSet.Auto)]
private static extern bool CloseHandle(IntPtr handle);

}

Wednesday, August 19, 2009

Cool CSS vertical menu

Menu no. 1:




The article can be found here:
Simple CSS vertical menu Digg-like

Menu no. 2:

Make a Mega Drop-Down Menu with jQuery



The article can be found here:

Make a Mega Drop-Down Menu with jQuery

Wednesday, April 15, 2009

Membership Management for ASP.NET MVC release 1.0

update: checkout this post: Visual Studio Content Installer for Asp.Net MVC Membership Management

With the release of Microsoft Visual Studio 2005, there is no "out of the box" solution for maintaining the Membership and Role databases in Microsoft IIS. This is a problem when you move your application from development to a production IIS server. The utility that Microsoft provides, ASP.NET Web Configuration, can be run only in a development, non-production environment.

This sources and its associated code solve this by implementing solution to Member and Role management while using standard Microsoft ASP.NET MVC tools. This means that it will run in any ASP.NET MVC 1.0 environment, including IIS.

I found 3 projects for membership management were 2 of them are outdated and one is not working with current asp.net mvc release 1.0 (ASP.Net MVC Membership Starter Kit). Some of my code is based on the started kit but most stuff I had to rewrite or make coding changes to make it work with asp.net mvc release 1.0.

I'm writing already 2 open source projects therfore I'm not able to share this sources for free and I plan to sell you full source bundle for around 30 EURO. In the meanwhile, if you're interessted in the code you welcome to drop me a line (schuetz [@] gmail [dot] com).

Please use this page to donate the amount.


Please notice that MVC is a precondition for this project.

The asp.net mvc membership management contains the following functionality:

  • Dashboard
  • Browse Users
  • User -> Details
  • User -> User's Roles
  • User -> Reset Password
  • User -> Delete User
  • Browse Roles
  • Roles -> Users in Roles
  • Statistical Information
  • Statistical Information -> Registerd users past 7 days (visualization with chart.apis.google.com)
  • Statistical Information -> Registerd users past 12 months (visualization with chart.apis.google.com)
  • Statistical Information -> Not approved users past 12 months (visualization with chart.apis.google.com)

Additinal functionality will be implemented after rel. 1. Have a look at the following printscreens to get an impression what you'll get. I plan to extend this unti l its gonna be a real managment application and as more people will use it as bigger the motivation :-)

INFO: ALL UPDATES WILL BE FREE!!














Sunday, December 28, 2008

Justin Etheredge: How To Guarantee That Your Software Will Suck

Justin Etheredge wrote an article: How To Guarantee That Your Software Will Suck

here is an overview:

1) Don't give your developers the tools they need to do their jobs.
2) Just jump right in, plans are for chumps.
3) Set strict deadlines on projects that will take "tens of thousands of man hours".
4) Spend hundreds of hours writing ridiculously detailed documentation.
5) Refuse to buy them more than one monitor.
6) Buy cheap hardware.
7) Keep asking them to multi-task.
8) Write everything yourself.
9) Expect your developers to sit quietly in front of their computer 8 hours a day.
10) Purchase tools without consulting those who will have to use them.

some of the points i absolutely agree with :-)

Thursday, August 14, 2008

Check if server is available before you make requests

I had to implement a fallback system in case one of my primary servers is not available anymore because of any reason. There were no option to access servers over a loadbalancer or something else then a direct routing to each server.

After some compassion's how much time I gone waste for each request between usage of sockets or HttpWebRequest / WebRequest I decided to work directly with Sockets.

The implementation I decided to go for were quite easy (remember: keep it simple as possible) and its fast like hell - 9ms I'm loosing each check if the server is available or not. We use 2 servers - so I have to remember that there is a total of 18ms I'm loosing each time we have a running cycle to analyse data. In general my tests gave showed me that 5 of the 9 ms are used for DNS.GetHostEntry(ServerName) - if you can use IP-Addresses then I suggest to do it that way. Check out one of my previous post about this DNS.GetHostEntry(ServerName) - IPAddress.Parse("127.0.0.1") vs. Dns.GetHostEntry("127.0.0.1")

With those ~20ms we can leave very good because a cycle needs right now something around 2.5min and it can be a max. of 15min. So how to solve this is the question, here the codesample from MSDN which I adapted and using to validate if my servers are online: http://msdn.microsoft.com/en-us/library/system.net.sockets.socket.aspx

Formatted Code is available here: http://www.ronischuetz.com/code/CheckIfServerIsAvailable.htm



   1:      private static bool ConnectSocket(string server, int port)

   2:      {

   3:          Stopwatch sp = new Stopwatch();

   4:          IPHostEntry hostEntry = null;

   5:          bool result = false;

   6:          sp.Start();

   7:          // Get host related information.

   8:          hostEntry = Dns.GetHostEntry(server);

   9:          sp.Stop();

  10:          Log.Info(string.Format("ConnectSocket->Dns.GetHostEntry({0}) needed: {1}ms ",server, sp.ElapsedMilliseconds));

  11:          sp.Reset();

  12:   

  13:          // Loop through the AddressList to obtain the supported AddressFamily. This is to avoid

  14:          // an exception that occurs when the host IP Address is not compatible with the address family

  15:          // (typical in the IPv6 case).

  16:          foreach (IPAddress address in hostEntry.AddressList)

  17:          {

  18:              sp.Start();

  19:              IPEndPoint ipe = new IPEndPoint(address, port);

  20:              Socket tempSocket = new Socket(ipe.AddressFamily, SocketType.Stream, ProtocolType.Tcp);

  21:              tempSocket.ReceiveTimeout = 1000;

  22:              tempSocket.SendTimeout = 1000;

  23:              // this is very important!!! Do not delete this.

  24:              tempSocket.NoDelay = true;

  25:              

  26:              try

  27:              {

  28:                  tempSocket.Connect(ipe);

  29:                  #region Status Check

  30:                  if (tempSocket.Connected)

  31:                  {

  32:                      #region Connnected Section

  33:                      result = true;

  34:                      if (tempSocket != null)

  35:                      {

  36:                          try

  37:                          {

  38:                              tempSocket.Shutdown(SocketShutdown.Both);

  39:                              tempSocket.Close();

  40:                          }

  41:                          catch (Exception ex)

  42:                          {

  43:                              // do nothing - only release resources and don't let the system fuck up

  44:                          }

  45:                          finally

  46:                          {

  47:                              tempSocket = null;

  48:                          }

  49:                      }

  50:                      #endregion Connnected Section

  51:                      break;

  52:                  }

  53:                  else

  54:                  {

  55:                      continue;

  56:                  }

  57:                  #endregion End Status Check

  58:              }

  59:              catch (Exception ex)

  60:              {

  61:                  string title = string.Format("Could not connect to server:{0}:{1} -  " + Environment.NewLine + ex.Message + Environment.NewLine + ex.StackTrace, server, port);

  62:                  Log.Info(title);

  63:                  Log.Fatal(title);

  64:                  result = false;

  65:              }

  66:   

  67:              sp.Stop();

  68:              Log.Info(string.Format("ConnectSocket->hostEntry.AddressList({0}) needed: {1}ms to connect to server ", ipe.Address.ToString(), sp.ElapsedMilliseconds));

  69:              sp.Reset();

  70:          }

  71:          return result;

  72:      }
 
 

Tuesday, July 08, 2008

triage bugs ...

today I found an interesting post about bugs and how people triage bugs:

Wil Shipley has written it down, in his blog post: "Pimp My Code, Part 15: The Greatest Bug of All" the following ordering which I totally agree with how bugs should be triage:

  • Data-loss bugs
  • Unavoidable crashers
  • Functionality-blocking bugs
  • Avoidable crashers
  • Avoidable bugs
  • Misfeatures
  • Performance issues
  • Feature suggestions
  • UI feedback

Wednesday, April 16, 2008

indeXus.Net Shared Cache goes NHibernate Ver. 1.2.1

NHibernate Ver. 1.2.1

NHibernate is a port of
Hibernate Core for Java to the .NET Framework. It handles persisting plain .NET objects to and from an underlying relational database. Given an XML description of your entities and relationships, NHibernate automatically generates SQL for loading and storing the objects. Optionally, you can describe your mapping metadata with attributes in your source code.

NHibernate.Caches.SharedCache provider for indeXus.Net Shared Cache (
http://www.sharedcache.com/)

Get your copy at the following location:
http://jira.nhibernate.org:8080/jira/browse/NH-1276

read more: http://www.sharedcache.com/cms/default.aspx?pg=74ae4aae-ad0e-4c4c-b2c2-3b3218c1ef20

Sunday, February 10, 2008

Threaded Asynchronous Tcp Server with a blocking Client

I don't know now how many prototypes I have written in the past few weeks to verify which approach would fit best to scale and be most performance for indeXus.Net Shared Cache. To write a Client / Server Architecture which mostly will be N:M connectivity was not that easy as I thought in beginning.

Honestly I believe I have study every single C# sample I found on the common search engines and arrived to the point where I started to adapt the samples. Unfortunately 99% of founded samples are showing how to pass a string from the client to the server beside one blog which has written down a lot of theory and some very nice diagrams without to come up with code. I only can recommend you to read this blog up and down before you write even one single line of code: http://www.coversant.net/Coversant/Blogs/tabid/88/EntryID/10/Default.aspx. There are some very smart people around they have done great work.

After a while of research, I get to koders.com where I found a strip-down version of their product.

Another very useful page with a lot of sample code around .net is Mike Woodrings's .net Sample Page which contains a bunch of great examples for different domains.

I think I have tried any way to use Sockets now:


  • Blocked Sockets
  • Unblocked Sockets
  • Poll Sockets
  • Select

Every prototype I have done so far had his advantages and disadvantages. In the end of this post I will provide 2 downloads:

  • prototype with poll sockets on client and server
  • protptype with block sockets on client side and async server handling
Once I get comfortable with all the different Issues which come across the write the server part I decided to use Asad Aziz - Asynchronous Server Socket using C# Sample as my base for the server. Its very easy written but my knowledge on this issue was limited until I started to work on it quite intensive and I think I learned every day at least 10 new things :-)

Lets dive into different key parts of the client and the server. An additional issue I would like to mention here is that the whole code is 100% managed.

We gone start first with the server. As already mention the server is working Asynchronous which means we have to handle with IAsyncResult. Upon Server start we begin run the server within a different thread and the client cleanup will be handled by a TimerCallback to purge disconnected clients in case they not removed before upon disconnection.

ThreadStart serverListener = new ThreadStart(this.StartListening);
serverThread[0] = new Thread(serverListener);
serverThread[0].IsBackground = true;
serverThread[0].Start();
TimerCallback timerDelegate = new TimerCallback(this.CheckSockets);
this.lostTimer = new Timer(timerDelegate, null, SharedCacheTcpServer.timerTimeout, SharedCacheTcpServer.timeoutMinutes);

Since we have started now the serverListener we Bind the server IPEndPoint to the requested ip and port and start to listen for connections from clients. Once a connection is received it only will be destroyed in one of the following 2 cases:

  1. The Socket has not been used for a certain amount of time
  2. Client Socket get disconnected.

With this we avoid to much Server resources. As started we will use a ManualResetEvent to accept only one by one client. I have commented this part for testing purposes and the server started to throw memory exceptions. So keep it simple in the meaning, only start a new BeginAccept once you finished to move the client into AccecptCallback.

private void AccecptCallback(IAsyncResult ar)
{
// signal main thread to continue
this.allDone.Set();
Socket clientListener = ar.AsyncState as Socket;
if (clientListener != null)
{
Socket handler = clientListener.EndAccept(ar);
Console.WriteLine(@"Connected by client: {0}", handler.RemoteEndPoint);
StateObject state = new StateObject();
state.WorkSocket = handler;
state.AliveTimeStamp = DateTime.Now;

... and some more code ..

once you have done all setup for you StateObject (this is the object which contains all different data between the calls) we able to call BeginReceive. SharedCache Protocol between client and server keep simple: [messageLength][message] so if we are not able to get the whole message at once we have to call several times BeginReceive until we have received everything from the client and we able to run the custom stuff on the server.

Once we done with our reading we can start to process received package and process with it. To keep server resources (amount of threads) under control I decided to use Mike's Threadpool.


I think the 2 most important parts are within this message is to know that we need to read the header which indicates to message length and if we need to read more data for this message or do we can proceed it arrived data.

// check for header
if (state.ReadHeader) { .....


// check for message length -> TODO: how to check longer values as int count in list????
if (state.DataBuffer.ToArray().LongLength == state.MessageLength) { ...


as you can see there is even one open point since I use in my state object a List. I had some discussions with people on asp.net forums but I believe i can life right now with this
int.MaxValue as maximal message length ;-)


the next key position in above code print screen is that we use at this place again handler.BeginReceive() since we want to client connection keep opened as long as possible. Some previous tests had shown me while i open and close 1000 Sockets the time reduction to use always the same is more then 50%. Before we can post the request into ThreadPool we need to remove the Range of our message size [8 bytes] that's why we do: state.DataBuffer.RemoveRange(0,8); once we have posted it to the threadpool to pool handles the message sending the Echo to the waiting client.
HandleClientMessage is the place which is called after you get the free Thread from the ThreadPool - here you can manage your Server side stuff and once you done you can send it back to the Client. If you work within Winform environment a more event driven design would be correct but for sharedcache this would not be correct since the client is waiting for the server response.



in the above example we do nothing else then to set an Attribute of the object IndexusMessage to Successful.
The response from the server needs to be prepared, then also the client waits for the same struct [message length][message data]. Therefore we call UtilByte.CreateMessageHeader(with the msg.GetBytes() which returns a byte array) and we combine both values to 1 single byte array. since this is done we can free up resources and set the actual messageLength on the state so we know how much data we need to send to the client which is not less important.



Within the Send() method we start the async call: socket.BeginSend() or if we do not have anything to send back (this case does not happen here) we reset all state data and start to receive again without to destroy the state and the socket which is included in the state. The
same idea happens within the SendCallback() we call BeginSend() as long we have data to send and once we sent everything to the client we reset the state and start to receive again with socket.BeginReceive().

These are all important parts on the server side, I will wrap up the client in a different post within the next few days.

The 2 best code-solution I have found on the web are the following 2 links:

http://www.codeproject.com/KB/IP/Generic_TCP_IP_server.aspx
http://www.codeproject.com/KB/IP/AsyncSocketServerandClien.aspx

Both of them could not handle the case I needed so I hope people can use the Prototypes in this or another way. It would be great if you let me know if you are using them. So here are the downloads:


I really would like to say "thank you very much" to all contributors of the following articles and coding samples:

Monday, February 04, 2008

IPAddress.Parse("127.0.0.1") vs. Dns.GetHostEntry("127.0.0.1")

Did you ever come to the point where you had to get several times an System.Net.IPEndPoint? The constructor takes an IPAddress and a specific Port which you select... Now guess what... if you handle with known IPAddresses within your Network you should not use Dns.GetHostEntry just because its very very very slow, as long you know the IP Address ;-). In almoast every online example I have seen so far online I always have seen usage of Dns.GetHostEntry.... people thats so wrong in my point of view and after my measurment - correct me if I'm wrong but I love to measure :-) !

Once you deal with other issues maybe there is no other way but since a while I grab the WWW around tcp and udp socket issues and one of this issues is to give a solution with object pooling while a unexpected load arrives on a web-server and it needs to open more then the expected amount of sockets to its server. So here we can have e.g. instead of the normal 20 open connections fast 120 - 150 additional sockets. This additional instances are there for a certain time amount and afterwards they get closed again but even then. If you need to be fast, then every millisecond counts since we are talking about scalability.

In general I gone compare about the following code lines:

IPEndPoint ep = new IPEndPoint(IPAddress.Parse("127.0.0.1"), 48888);

and

IPEndPoint ep = new IPEndPoint(Dns.GetHostEntry("127.0.0.1").AddressList[0], 48888);

I have done a small test to measure if this two options are really have such a hugh difference:

Run no. 1 with: 127.0.0.1

IP-Address Parse average: 6 milliseconds
5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 8

DNS GetHostEntry average: 125 milliseconds
56, 57, 66, 67, 68, 70, 70, 71, 71, 72, 78, 78, 79, 80, 81, 81, 82, 82, 83, 85, 86, 87, 88, 88, 91, 95, 96, 96, 97, 97, 98, 99, 99, 101, 102, 103, 104, 106, 110, 111, 113, 114, 116, 117, 118, 119, 122, 127, 128, 129, 130, 130, 131, 133, 143, 144, 144, 145, 145, 146, 146, 147, 148, 148, 149, 150, 155, 155, 156, 157, 158, 158, 159, 159, 160, 161, 161, 162, 162, 163, 164, 165, 166, 167, 169, 169, 170, 171, 172, 173, 173, 174, 175, 175, 176, 177, 177, 178, 178, 179,


Run no. 2 with: 192.168.xxx.21

IP-Address Parse average: 11 milliseconds
10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11,11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12,12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12
DNS GetHostEntry average: 168 milliseconds
95, 99, 100, 101, 105, 106, 106, 109, 110, 112, 121, 121, 122, 123, 124, 125, 126, 132, 133, 134, 136, 137, 139, 141, 141, 143, 144, 146, 148, 153, 153, 155, 155, 156, 157, 157, 160, 163, 163, 164, 165, 166, 168, 168, 169, 170, 170, 173, 177, 177, 178, 179, 180, 180, 181, 181, 182, 182, 183, 184, 184, 185, 186, 186, 187, 187, 188, 191, 192, 193, 193, 194, 195, 195, 196, 197, 197, 198, 199, 200, 201, 202, 203, 203, 204, 205, 206, 206, 207, 207, 208, 208, 209, 210, 211, 211, 215, 217, 218, 218,

incredible how much the difference is.

The formatted code is available over here: http://www.ronischuetz.com/code/IpParseVsDnsGetHostEntry.html
and the c# version you can get from here:
http://www.ronischuetz.com/code/IpParseVsDnsGetHostEntry.cs.txt

Friday, February 01, 2008

.net C# code helper serie

I have no clue how many times you are writing the same code but I will start to use the blog for several helper classes I'm using all the time again and again and again.


This series starts with the System Information Helper class. This class helps to provide System Information for Windows Environments. The parts of the class are the following onces:

  • Get .net framework information
  • Get Operating System
  • Get the name of the system machine
  • Get the current executing location
  • Get config files in executing location
  • Get the current user

The code can be dowloaded from the following location: http://www.ronischuetz.com/code/SysInfo.cs.txt or just have a look at the formatted version: http://www.ronischuetz.com/code/sysinfo.cs.html.

If you send me some additional parts I will extend the post.

Saturday, January 26, 2008

DUMPBIN - thats cool

get know of your assemblies with dumpbin

The Microsoft COFF Binary File Dumper (DUMPBIN.EXE) displays information about 32-bit Common Object File Format (COFF) binary files. You can use DUMPBIN to examine COFF object files, standard libraries of COFF objects, executable files, and dynamic-link libraries (DLLs).

http://support.microsoft.com/kb/177429

An interface has been developed for this nice tool: http://www.cheztabor.com/dumpbinGUI/index.htm

.Net CLR Memory Performance Monitoring

If you need to monitor you memory the usage of Perfmon is needed to start. There are also some shareware and MS CLR Profiler available but lets explain the basic's for the usage of Perfmon.

to start perfmon: start -> run: type: perfmon and the Performance SnapIn window appears.



the window starts with some default counters, usually you those are not the counters you will have to look on. Therefor you need to choose the right selection, which you do with right click -> add counters. Then you can select your requested counters as shown below:




Lets describe the different counters we have:

  • # Bytes in all Heaps: This counter is the sum of four other counters; Gen 0 Heap Size; Gen 1 Heap Size; Gen 2 Heap Size and the Large Object Heap Size. This counter indicates the current memory allocated in bytes on the GC Heaps.
  • # GC Handles: This counter displays the current number of GC Handles in use. GCHandles are handles to resources external to the CLR and the managed environment. Handles occupy small amounts of memory in the GCHeap but potentially expensive unmanaged resources.
  • # Gen 0 Collections: This counter displays the number of times the generation 0 objects (youngest; most recently allocated) are garbage collected (Gen 0 GC) since the start of the application. Gen 0 GC occurs when the available memory in generation 0 is not sufficient to satisfy an allocation request. This counter is incremented at the end of a Gen 0 GC. Higher generation GCs include all lower generation GCs. This counter is explicitly incremented when a higher generation (Gen 1 or Gen 2) GC occurs. _Global_ counter value is not accurate and should be ignored. This counter displays the last observed value.
  • # Gen 1 Collections: This counter displays the number of times the generation 1 objects are garbage collected since the start of the application. The counter is incremented at the end of a Gen 1 GC. Higher generation GCs include all lower generation GCs. This counter is explicitly incremented when a higher generation (Gen 2) GC occurs. _Global_ counter value is not accurate and should be ignored. This counter displays the last observed value.
  • # Gen 2 Collections: This counter displays the number of times the generation 2 objects (older) are garbage collected since the start of the application. The counter is incremented at the end of a Gen 2 GC (also called full GC). _Global_ counter value is not accurate and should be ignored. This counter displays the last observed value.
  • # Induced GC: This counter displays the peak number of times a garbage collection was performed because of an explicit call to GC.Collect. Its a good practice to let the GC tune the frequency of its collections.
  • # of Pinned Objects: This counter displays the number of pinned objects encountered in the last GC. This counter tracks the pinned objects only in the heaps that were garbage collected e.g. a Gen 0 GC would cause enumeration of pinned objects in the generation 0 heap only. A pinned object is one that the Garbage Collector cannot move in memory.
  • # of Sink Blocks in use: This counter displays the current number of sync blocks in use. Sync blocks are per-object data structures allocated for storing synchronization information. Sync blocks hold weak references to managed objects and need to be scanned by the Garbage Collector. Sync blocks are not limited to storing synchronization information and can also store COM interop metadata. This counter was designed to indicate performance problems with heavy use of synchronization primitives.
  • # Total committed Bytes: This counter displays the amount of virtual memory (in bytes) currently committed by the Garbage Collector. (Committed memory is the physical memory for which space has been reserved on the disk paging file).
  • # Total reserved Bytes: This counter displays the amount of virtual memory (in bytes) currently reserved by the Garbage Collector. (Reserved memory is the virtual memory space reserved for the application but no disk or main memory pages have been used.)
  • % Time in GC: % Time in GC is the percentage of elapsed time that was spent in performing a garbage collection (GC) since the last GC cycle. This counter is usually an indicator of the work done by the Garbage Collector on behalf of the application to collect and compact memory. This counter is updated only at the end of every GC and the counter value reflects the last observed value; its not an average.
  • Allocated Bytes/sec: This counter displays the rate of bytes per second allocated on the GC Heap. This counter is updated at the end of every GC; not at each allocation. This counter is not an average over time; it displays the difference between the values observed in the last two samples divided by the duration of the sample interval.
  • Finalization Survivors: This counter displays the number of garbage collected objects that survive a collection because they are waiting to be finalized. If these objects hold references to other objects then those objects also survive but are not counted by this counter; the "Promoted Finalization-Memory from Gen 0" and "Promoted Finalization-Memory from Gen 1" counters represent all the memory that survived due to finalization. This counter is not a cumulative counter; its updated at the end of every GC with count of the survivors during that particular GC only. This counter was designed to indicate the extra overhead that the application might incur because of finalization.
  • Gen 0 Heap Size: This counter displays the maximum bytes that can be allocated in generation 0 (Gen 0): its does not indicate the current number of bytes allocated in Gen 0. A Gen 0 GC is triggered when the allocations since the last GC exceed this size. The Gen 0 size is tuned by the Garbage Collector and can change during the execution of the application. At the end of a Gen 0 collection the size of the Gen 0 heap is infact 0 bytes; this counter displays the size (in bytes) of allocations that would trigger the next Gen 0 GC. This counter is updated at the end of a GC; its not updated on every allocation.
  • Gen 0 Promted Bytes/Sec: This counter displays the bytes per second that are promoted from generation 0 (youngest) to generation 1; objects that are promoted just because they are waiting to be finalized are not included in this counter. Memory is promoted when it survives a garbage collection. This counter was designed as an indicator of relatively long-lived objects being created per sec. This counter displays the difference between the values observed in the last two samples divided by the duration of the sample interval.
  • Gen 1 heap size: This counter displays the current number of bytes in generation 1 (Gen 1); this counter does not display the maximum size of Gen 1. Objects are not directly allocated in this generation; they are promoted from previous Gen 0 GCs. This counter is updated at the end of a GC; its not updated on every allocation.
  • Gen 1 Promted Bytes/Sec: This counter displays the bytes per second that are promoted from generation 1 to generation 2 (oldest); objects that are promoted just because they are waiting to be finalized are not included in this counter. Memory is promoted when it survives a garbage collection. Nothing is promoted from generation 2 since it is the oldest. This counter was designed as an indicator of very long-lived objects being created per sec. This counter displays the difference between the values observed in the last two samples divided by the duration of the sample interval.
  • Gen 2 heap size: This counter displays the current number of bytes in generation 2 (Gen 2). Objects are not directly allocated in this generation; they are promoted from Gen 1 during previous Gen 1 GCs. This counter is updated at the end of a GC; its not updated on every allocation.
  • Large Object Heap Size: This counter displays the current size of the Large Object Heap in bytes. Objects greater than 20 KBytes are treated as large objects by the Garbage Collector and are directly allocated in a special heap; they are not promoted through the generations. This counter is updated at the end of a GC; its not updated on every allocation.
  • Process ID: This counter displays the process ID of the CLR process instance being monitored.
  • Promted Finalization-Memory from Gen 0: This counter displays the bytes of memory that are promoted from generation 0 to generation 1 just because they are waiting to be finalized. This counter displays the value observed at the end of the last GC; its not a cumulative counter.
  • Promted Memory from Gen 0: This counter displays the bytes of memory that survive garbage collection (GC) and are promoted from generation 0 to generation 1; objects that are promoted just because they are waiting to be finalized are not included in this counter. This counter displays the value observed at the end of the last GC; its not a cumulative counter.
  • Promted Memory from Gen 1: This counter displays the bytes of memory that survive garbage collection (GC) and are promoted from generation 1 to generation 2; objects that are promoted just because they are waiting to be finalized are not included in this counter. This counter displays the value observed at the end of the last GC; its not a cumulative counter. This counter is reset to 0 if the last GC was a Gen 0 GC only.

GC.Collect - how it really works - .net Garbage Collection

The GC (Garbage Collection) in .Net is a Win32 process within HEAP which is initially created by the OS (Operation System) based on CLR request. This request add 2 segments of 16 MB each (16kb committed). One of them is allocated for the Gen0, Gen1 & Gen2 and the second segment is used for LOH (Large Object Heap). Objects greater than 20 KBytes are treated as large objects by the Garbage Collector and are directly allocated in a special heap

While we start to create small objects the first segment starts to grow. If we suppose that we keep all instantiated objects without ever releasing any instance until the segment gets full, the CLR ask OS for another segment of 16MB (16kb committed) and continues to allocate object space from that new segment which has been received by the operating system.

If we free up memory, lets suppose all allocated 32 MB, CLR leaves you still with a HEAP size of 32 MB even that nothing is committed. The GC still held all free space and will not return it to the OS until we use a memory pressure.

With the memory pressure the operating system sending a signal to the CLR to trim the working set and the CLR will return additional segments to OS.

The conclusion of it is simple, there is plenty of free memory and the operating system does not claim anything from running processes.

Friday, January 25, 2008

Performance average comparsion between State Server and indeXus.Net Shared Cache

Performance Environment and preconditions:
Client: MS Windows XP Prof, Intel Pentium D, 2.8GHz, 3.24 GB RAM
Server: MS Windows Server 2003, Enterprise Edition SP2, Intel Pentium D, 2.8GHz, 3.24 GB RAM
Iterations: 1000

Object Size: ~1kb
Debug Mode: True

Session State on same server:
In-Process: 225 requests / second
Out-Of-Process: 165 requests / second

Session State on remote server:
Out-Of-Process, 55 requests/second (-68%)

indeXus.Net Shared Cache same server:
add: 3s 128ms -> 319.6 req/sec
get: 3s 096ms -> 322.3 req/sec
remove: 2s 868ms -> 348.6 req/sec

indeXus.Net Shared Cache remote server:
add: 3s 425ms -> 291.9 req/sec
get: 3s 620ms -> 276.2 req/sec
remove: 3s 556ms -> 297.9 req/sec



original page:
http://www.codeplex.com/SharedCache/Wiki/View.aspx?title=Speed%20Test%20Results

additional comparsions will be added soon, also with sql server

Thursday, January 17, 2008

sorting dictionary by value

oh hell how i didn't thought about this before!!!


public static Dictionary<string,long> SortDictionary(Dictionary<string,long> data)
{
  List<keyvaluepair<string,long>> result =
        new List<keyvaluepair<string,long>>(data);
  result.Sort(
    delegate(
      KeyValuePair<string,long> first,
      KeyValuePair<string,long> second)
        {
          return second.Value.CompareTo(first.Value);
        }
    );
  return data;
}

if you want the smallest amount be on top you need to switch the following line from:

return second.Value.CompareTo(first.Value);

to

return first.Value.CompareTo(second.Value);


the same method you can use also for: Dictionary<string,int> or Dictionary<string,string> or each value type of your choice.

--
happy sort of dictonary by value ;-) yes I love generics ... just sometimes I don't see through its possibilites

Wednesday, January 16, 2008

Text File does not get deployed from Class Library Project into Asp.NET Web Application

The issue sounds simple to me:

Text File does not get deployed from Class Library Project into Asp.NET Web Application

"We have a webproject and would like to deploy HTML and
Text Templates from a common Project into the web project
output folder.

The Attributes on the text / html files are set like this:
Build Action: Content
Copy to Output Directory: Copy Always
it just copy the files into the common csharp project under the bin/debug
but it doesn't appears within the web project.

any idea how to solve this issue without a lot of post build scripts?"

This have been posted 2 days ago I posted the following problem at:
http://forums.asp.net/t/1205184.aspx

To fix this issue you simply need to think in different direction - the oposite one :-)

Step 1: Don't add your files you would like to share in TFS (Team Foundation Server) into your Class Library Project - add files (html / xml / text / etc.) into your App_Data folder in your Asp.NET Web Application Project Type.
Step 2: Create your Folder within your Class Library Project you like to have the files. Once you have created the folder, you can right click on the folder and select : Add -> Existing Item

This will open you a dialog folder with a small HINT which is the BIG SHOOT for this issues. Don't simply add it while you press "Add" you need to select the small arrow near the Button and select "Add As Link" like the below printscreen shows:















Once you have done above steps, select your file and look at the file properties within your Visiual Studio. There you find some Attributes you need to check, you should check that the "Build Action:" is equal to "Content" and the "Copy to Output Directory:" is set to "Copy Always" or "Copy if newer".

In my case I do not need now to held the files redunded and sync them upon changes ....


just think different you will solve the problem!! was the motto upon this issue !

Wednesday, December 26, 2007

indeXus.Net Shared Cache V1 is available

I finally have released the first version of indeXus.Net Shared Cache which is available at: http://www.sharedcache.com/.

indeXus.Net SharedCache is a high-performance, distributed caching system. Although application-neutral, it's commonly used to speed up dynamic Web applications by alleviating database load.

indeXus.Net SharedCache runs as a distributed windows service on every web and / or application server farm to cache data objects in memory out of process. Your stored objects can be accessed from any of your servers in your farm. It would be great if you help me to make it public through usage and blog entries. The release notes are available at the following location: https://www.codeplex.com/Release/ProjectReleases.aspx?ProjectName=SharedCache&ReleaseId=9424

for any queries about sharedcache please use the following email:
sharedcache [AT] indeXus [DOT] Net

Saturday, December 22, 2007

a simple und strightforward way to sort generic List

Sorting in general with generic list is quite easy if the developer knows how to do the sorting. With simple anonymous methods, as well the little known Comparsion delegate.

In one of my previous posts (caching cleanup strategy) I described a specific problem I have to solve for SharedCache, the .Net caching solution for distributed cache: http://www.sharedcache.com/ / http://www.codeplex.com/SharedCache

The following example here is just partly, the full code will be available within a few day's on CodePlex - upon my next hugh checkin .... people i'm a bit afraid to check it in sometimes it has so many new features ;-) - that i say as a person which preferres the way of: make small steps your reach your target faster!!!!

a simple sample class (a full formatted working class sample from my project):

   1:      public class Cleanup : IComparable<Cleanup>
   2:      {
   3:          string yourProperty = string.Empty;
   4:          public enum SortingOrder
   5:          {
   6:              /// <summary>
   7:              /// ascending sorting order
   8:              /// </summary>
   9:              Asc,
  10:              /// <summary>
  11:              /// descending sorting order
  12:              /// </summary>
  13:              Desc
  14:          }
  15:          public int CompareTo(Cleanup other)
  16:          {
  17:              return this.yourProperty.CompareTo(other.yourProperty);
  18:          }
  19:          public static Comparison<Cleanup> CacheItemPriority =
  20:              delegate(Cleanup cu1, Cleanup cu2)
  21:              {
  22:                  if (Cleanup.Sorting == SortingOrder.Asc)
  23:                  {
  24:                      return cu1.yourProperty.CompareTo(cu2.yourProperty);
  25:                  }
  26:                  else
  27:                  {
  28:                      return cu2.yourProperty.CompareTo(cu1.yourProperty);
  29:                  }
  30:              };
  31:      }
Once you have defined your class, you are able to sort it like need, with Ascending and Descending sortings
the sample you find also formatted at here: http://www.ronischuetz.com/code/cachecleanup.html
   1:      public class CacheCleanup
   2:      {
   3:          public CacheCleanup()
   4:          { 
   5:              List<Cleanup> coll = new List<Cleanup>();
   6:              coll.Add(new Cleanup(IndexusMessage.CacheItemPriority.Normal, new TimeSpan(0, 1, 7), 1, new DateTime(2007, 12, 28, 14, 12, 12), 21232, 90));
   7:              coll.Add(new Cleanup(IndexusMessage.CacheItemPriority.AboveNormal, new TimeSpan(0, 15, 7), 2, new DateTime(2007, 12, 28, 14, 12, 14), 22232, 190));
   8:              coll.Add(new Cleanup(IndexusMessage.CacheItemPriority.BelowNormal, new TimeSpan(0, 18, 7), 3, new DateTime(2007, 12, 28, 14, 12, 40), 23232, 88));
   9:              coll.Add(new Cleanup(IndexusMessage.CacheItemPriority.High, new TimeSpan(0, 8, 7), 4, new DateTime(2007, 12, 28, 14, 12, 16), 21552, 22));
  10:              coll.Add(new Cleanup(IndexusMessage.CacheItemPriority.Low, new TimeSpan(0, 9, 7), 5, new DateTime(2007, 12, 28, 14, 12, 17), 21252, 1));
  11:              coll.Add(new Cleanup(IndexusMessage.CacheItemPriority.NotRemovable, new TimeSpan(0, 22, 7), 6, new DateTime(2007, 12, 28, 14, 12, 19), 212332, 5));
  12:              coll.Add(new Cleanup(IndexusMessage.CacheItemPriority.AboveNormal, new TimeSpan(0, 41, 7), 7, new DateTime(2007, 12, 28, 14, 12, 22), 211232, 55));
  13:              coll.Add(new Cleanup(IndexusMessage.CacheItemPriority.BelowNormal, new TimeSpan(0, 58, 7), 8, new DateTime(2007, 12, 28, 14, 12, 21), 22532, 25));
  14:   
  15:              Console.WriteLine(@"Without Sorting");
  16:              foreach (Cleanup c in coll)
  17:              {
  18:                  Console.WriteLine(c.ToString());
  19:              }
  20:   
  21:              Cleanup.Sorting = Cleanup.SortingOrder.Asc;
  22:              coll.Sort(Cleanup.CacheItemPriority);
  23:              Console.WriteLine(@"Normal Sorting");
  24:              foreach (Cleanup c in coll)
  25:              {
  26:                  Console.WriteLine(c.ToString());
  27:              }
  28:   
  29:              Cleanup.Sorting = Cleanup.SortingOrder.Desc;
  30:              coll.Sort(Cleanup.CacheItemPriority);
  31:              Console.WriteLine(@"Reverse Sorting");
  32:              foreach (Cleanup c in coll)
  33:              {
  34:                  Console.WriteLine(c.ToString());
  35:              }
  36:          }
  37:      }

it's couldn't be easier :-)

Thursday, December 20, 2007

caching cleanup strategy

As many of the blog readers know, I develop in my spare time a .net caching component which is available under: http://www.sharedcache.com or http://www.codeplex.com/sharedcache. This component aims to be a high-performance, distributed memory object caching system, generic in nature, but intended to speeding up dynamic web and / or win applications by alleviating database load.

now since some different websites are using the cache (thanks for all your feedback's and inputs) the issue comes up to selectively purges items to free system memory.

Here are some options which I would love to hear your feedback's about them and about what you would need for your personal usage:

  • CacheItemPriority: A new option will be created where objects which are added to the cache receives a priority attribute.
  • LRU: Least Recent Used: The objects with the oldest requests will be deleted- LFU: Least Frequently Used: Means the object's witch are used less will be deleted from the cache / if all objects are used in same frequency the objects will be used in a randomized order
  • Pitkow/Recker: Like LRU, but if they used on same day they will not be deleted
  • Timebased: The objects with the smallest time left in the cache will be deleted, in case all objects are used with max time, they will be deleted randomized
  • SIZE: Delete always biggest objects until it received the size of FillFactor
  • Lowest-Latency-First: Delete smallest objects until configured FillFactor reached. in the app settings the customer will be able to define his cleaning strategy type as a key.
  • Hybrid: Makes a combination between several parameters: TimeTaken, Amount of Requests, Size, Cache Life Timeeach parameter receives a number between 1 - n and those with the highest / lowest numbers will be deleted until configured FillFactory reached.

I would love to receive your feedback's and inputs about it.

Shared Cache - .Net Caching made easy

All information about Shared Cache is available here: http://www.sharedcache.com/. Its free and easy to use, we provide all sources at codeplex.

Facebook Badge