Hallo,
ich hatte zuvor schon einen Thread geöffnet, in dem es um um eine Custom ConfigSection in der App.config ging.
Dieses Programm hatte ich nur erstellt, um einen Fehler zu finden:
Ich habe eine Art DienstManager, der verschiedene Threads (mittels Timer) startet, um verschiedenen Funktionen zu starten. Die Funktionen greifen alle auf die App.Config zu (um z.b. den nächsten Start des jeweiligen Dienstes zu setzen)
Dafür habe ich der app.config verscheidene ConfigSections hinzugefügt.
Es kommt nun (immer öfter) vor, dass eine komplette ConfigSection aus der app.config verschwindet.
Ich nahm an, dass das evtl. durch parallele Zugriffe (Save) auf die app.config passiert. Dies scheint aber nicht der Fall zu sein.
Hat irgendjemand eine Idee, wie das passieren kann?
Wenn ich auf die app.config zugreife dann nur:
* Durch die elemente einer ConfigSection iterieren, und dort ein attribut ändern
* danach mittels Configuration.Save() die sachen sichern.
Hallo reneGfm,
wenn du da was manipulierst und es in der Datei zu Datenverlust kommt ist mit Sicherheit dein Tun irgendwie damit verbunden. Wie auch immer: Ohne Code können wir nichts sagen. Sicher, dass du alle Zugriffe synchronisiert hast etc.?
Gruss
Coffeebean
Microsoft MVP // Me // Blog // GitHub // @Egghead // All my talks // Speakerdeck
habe ja wegen den parallelen Zugriffen extra ein TestPorgramm geschrieben: Der parallele Zugriff wirft nur eine Exception, aber löscht nicht meine Section.> Fehlermeldung:
Windows/.Net: Error in config.Save():Der Prozess kann nicht auf die Datei "C:\Coding\Projects\Test\TestConfig\bin\Debug\TestConfig.vshost.exe.Config" zugreifen, da sie von einem anderen Prozess verwendet wird.
Mono/Linux: Error in config.Save():Sharing violation on path /srv/utility/TestConfig.exe.config
Hier ist der Teil der Funktion, die auf die Section (schreibend) zugreift.
Es wird auch immer nur auf ein Attribut (pro Element) schreibend zugegriffen - alle anderen Attribute werden nur gelesen.
protected override bool OnTimer()
{
Configuration Config = ConfigurationManager.OpenExeConfiguration(ConfigurationUserLevel.None);
ConfigAuswertung ConfigSection = (ConfigAuswertung)Config.GetSection(configSectionName);
bool Result = true;
Console.WriteLine("Anz:" + ConfigSection.Elements);
foreach (ConfigElementAuswertung ConfigItem in ConfigSection.Elements)
{
Console.WriteLine("Function:" + ConfigItem.Function);
Result &= CallFunction(ConfigItem);
}
//if (Result)
{
try
{
Config.Save();
}
catch (Exception ex)
{
SvcManager.log(this, "Fehler in OnTimer():" + ex.Message);
}
}
return (Result);
}
Kannst du sagen, wann die Einträge verschwinden?
Zur Laufzeit des Programmes oder wenn es z.B. gestartet/gebaut wird (beim Bauen könnte evtl. die Standard-App.config drübergebügelt werden)?
habe ja wegen den parallelen Zugriffen extra ein TestPorgramm geschrieben: Der parallele Zugriff wirft nur eine Exception, aber löscht nicht meine Section.
Vielleicht ist das aber nicht immer so. Ohne jetzt in die sourcen zu gucken, könnte es sein das einer deiner Threads gerade liest während der andere gerade die zu schreibende Section aus der AppCOnfig gekickt hatte, bevor er die Section wieder reinschreibt. Deine Tests mit dem Timer sind zwar gut gemeint, werden aber die Situation in der Anwendung vllt. nicht ganz genau Nachstellen können.
Wäre zwar schade wenn das in der derzeitigen Impl. möglich wäre (für mich ein Bug), aber man hat ja schon Pferde kotzen sehen 😃
Syncronisiere die Zugriffe mit lock, und schau ob dein Problem verschwindet. Ist eh schöner, da dann auch die Exceptions verschwinden.
Kannst du sagen, wann die Einträge verschwinden?
Zur Laufzeit des Programmes oder wenn es z.B. gestartet/gebaut wird (beim Bauen könnte evtl. die Standard-App.config drübergebügelt werden)?
Die Einträge verschwinden immer zur Laufzeit; wenn der Prozess schon einige Zeit läuft. Und es verschwindet immer die komplette Section.
@unconnected: ich werd das lock gleich mal einbauen und ein paar Tests fahren.
Danke euch für die Hilfe - werd wohl heute noch n Tag in das Problem investieren müssen 😦