pda-dev.de

DelphiFeeds.com

Add to Technorati Favorites

IT Projekte und Freelancer

We use the ABCpdf.NET PDF component for HTML to PDF conversion.

tracker

Jan 06

Im gerade frischen neuem Jahr – an dieser Stelle sei kurz allen Lesern ein frohes neues und erfolgreiches 2010 gewünscht :) – wurde ich direkt mit dem Deployment eines IIS 7-gehosteten WCF-Service auf einem Web-Server mit Windows 2008 konfrontiert, dessen Website auf mehrere Domains konfiguriert ist.

Nahezu zwangsläufig (wie sich im Nachhinein herausstellen sollte) lief ich in die Falle und stolperte über den Fehler

This collection already contains an address with scheme http.  There can be at most one address per scheme in this collection. Parameter name: item

Nach – zum Glück – (relativ) kurzer Suche fand ich ein paar hilfreiche Blog-Einträge, aber ganz besonders erhellend waren für mich die folgenden Beiträge von Keith Elder, die ich daher an dieser Stelle für mich und jeden interessierten Leser verlinken möchte:

http://keithelder.net/blog/archive/2008/01/17/Exposing-a-WCF-Service-With-Multiple-Bindings-and-Endpoints.aspx

http://keithelder.net/blog/archive/2008/04/28/Configuring-WCF-and-IIS-7-With-HTTP-Bindings-and-Multiple.aspx

http://keithelder.net/blog/archive/2008/03/23/What-Software-Developers-Can-Learn-from-Forrest-Gump.aspx

Kick it on dotnet-kicks.de
Apr 17

Gestern war ich auf der Suche nach einem hartnäckigen, sich gut tarnenden Fehler in einer ASP.NET-Applikation unter .NET 3.5 SP 1 auf einem IIS 6 unter Windows Server 2003. Scheinbar sporadisch und nicht reproduzierbar verloren Anwender ab und zu die Session. Genauer gesagt, kam es zu einem unbeabsichtigten Restart der Application. Nachdem als Ursache die üblichen Verdächtigen ausgeschlossen werden konnten, habe ich letztendlich die _shutDownMessage der HttpRuntime durch Hinzufügen des folgenden Codes in die Global.cs analysieren können:

void Application_End(object sender, EventArgs e)
{
  var runtime = (HttpRuntime)typeof(HttpRuntime).InvokeMember("_theRuntime", BindingFlags.NonPublic | BindingFlags.Static | BindingFlags.GetField, null, null, null);

  if (runtime != null) {
    var shutDownMessage = (string)runtime.GetType().InvokeMember("_shutDownMessage", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.GetField, null, runtime, null);

    var shutDownStack = (string)runtime.GetType().InvokeMember("_shutDownStack", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.GetField, null, runtime, null);

    if (!EventLog.SourceExists(".NET Runtime")) {
      EventLog.CreateEventSource(".NET Runtime", "Application");
    }

    var log = new EventLog { Source = ".NET Runtime" };
    log.WriteEntry(String.Format("\r\n\r\n_shutDownMessage={0}\r\n\r\n_shutDownStack={1}", shutDownMessage, shutDownStack), EventLogEntryType.Error);
  }
}

Dadurch konnte ich die Fehlermeldung dir change or directory rename HostingEnvironment initiated caused shutdown directory rename sehen. Ursache war demnach ein Löschen temporär angelegter Ordner in einem Unterverzeichnis der Applikation.

Die permanente Überwachung des Applikationsordners (und seiner Unterordner) führte dazu, dass bei einem Löschen eines Ordners in dieser Struktur die Applikation neu gestartet wurde. Die File Change Notification lässt sich durch Eingriffe in die Registry ausschalten, aber dies war in diesem Fall weder erwünscht noch erlaubt.

Vielmehr habe ich nach kurzer Recherche eine Lösung in Microsofts ASP.NET-Forum gefunden:

  void Application_Start(object sender, EventArgs e)
  {
    //FIX disable AppDomain restart when deleting subdirectory
    //This code will turn off monitoring from the root website directory.
    //Monitoring of Bin, App_Themes and other folders will still be operational, so updated DLLs will still auto deploy.

    var p = typeof(HttpRuntime).GetProperty("FileChangesMonitor", BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Static);

    var o = p.GetValue(null, null);

    var f = o.GetType().GetField("_dirMonSubdirs", BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.IgnoreCase);

    var monitor = f.GetValue(o);

    var m = monitor.GetType().GetMethod("StopMonitoring", BindingFlags.Instance | BindingFlags.NonPublic);

    m.Invoke(monitor, new object[] { });
  }

Seitdem läuft die Anwendung ohne einen einzigen Session Restart durch.

Kick it on dotnet-kicks.de