Laden...

Forenbeiträge von reneGfm Ingesamt 5 Beiträge

17.08.2017 - 08:07 Uhr

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 😦

16.08.2017 - 16:21 Uhr

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);
		}
16.08.2017 - 15:07 Uhr

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.

16.08.2017 - 14:55 Uhr

Ursache scheint die Funktion

protected override object GetElementKey(ConfigurationElement element)

zu sein. Ich habe es etwas umgeschrieben und eine BasisElement Klasse erstellt, die einen Namen hat, der in der Funktion GetElementKey zurückgegeben wird.
Funktioniert nun

16.08.2017 - 10:50 Uhr

Hallo,

ich bekomme eine System.Configuration.ConfigurationErrorsException, wenn ich meine Config (app.config), die eine eigene configSections beinhalten, mittels Save() spreichere.

> Beim Ausführen des Konfigurationsabschnittshandlers für "SectionA" ist ein Fehler aufgetreten. Ungültiger Schlüsselwert

Ich finde den Fehler nicht.
Die Configuration wird korrekt geladen. Die CustomSection wird auch korrekt geladen und kann richtig gecastet werden. Aber beim Speichern knallt es.

Dies ist schon extra ein Test-Projekt, um den Fehler zu finden. Erfolglos.

Hauptfunktion: Bei Config.Save(); gibt es eine Exception.
Aber ich kann ganz normal auf die Eigenschaften des tempElement-Objekts zugreifen.


Configuration Config = ConfigurationManager.OpenExeConfiguration(ConfigurationUserLevel.None);
ConfigSectionA ConfigSection = (ConfigSectionA)Config.GetSection("SectionA");
ConfigSection.SectionInformation.ForceSave = true;
foreach (ConfigElementSectionA tempElement in ConfigSection.Elements)
{
	tempElement.value = "test";
}
Config.Save();

using System;
using System.Configuration;
using System.Collections.Generic;

namespace TestConfig
{

	/// #####################################################################################################################################
	/// <summary>
	/// 
	/// </summary>
	/// #####################################################################################################################################
	public class ConfigElementSectionA : ConfigurationElement
	{
		public ConfigElementSectionA()
		{
		}
		[ConfigurationProperty("name", IsRequired = true)]
		public string name
		{
			get { return (string)this["name"]; }
			set { this["name"] = value; }
		}
		[ConfigurationProperty("value", IsRequired = true)]
		public string value
		{
			get { return (string)this["value"]; }
			set { this["value"] = value; }
		}
	}


	public class GenericConfigurationElementCollection<T> : ConfigurationElementCollection, IEnumerable<T> where T : ConfigurationElement, new()
	{
		List<T> _elements = new List<T>();
		protected override ConfigurationElement CreateNewElement()
		{
			T newElement = new T();
			_elements.Add(newElement);
			return newElement;
		}
		public T this[int Index]
		{
			get
			{
				return (T)BaseGet(Index);
			}
			set
			{
				if (BaseGet(Index) != null)
					BaseRemoveAt(Index);
				BaseAdd(Index, value);
			}
		}
		protected override object GetElementKey(ConfigurationElement element)
		{
			return _elements.Find(e => e.Equals(element));
		}
		public new IEnumerator<T> GetEnumerator()
		{
			return _elements.GetEnumerator();
		}
	}



	/// #####################################################################################################################################
	/// <summary>	
	/// 
	/// </summary>
	/// #####################################################################################################################################
	public class ConfigSectionA : ConfigurationSection
	{
		ConfigElementSectionA element;
		public ConfigSectionA()
		{
			element = new ConfigElementSectionA();
		}
		public override bool IsReadOnly()
		{
			return false;
		}
		[ConfigurationProperty("elements", IsDefaultCollection = false)]
		[ConfigurationCollection(typeof(GenericConfigurationElementCollection<ConfigElementSectionA>), AddItemName = "add",
			ClearItemsName = "clear",
			RemoveItemName = "remove")]
		public GenericConfigurationElementCollection<ConfigElementSectionA> Elements
		{
			get
			{
				try
				{
					object x = base["elements"];
					return (GenericConfigurationElementCollection<ConfigElementSectionA>)x;
				}
				catch
				{
					return (null);
				}
			}
		}
	}
}

Edit app.config:

<?xml version="1.0" encoding="utf-8"?>
<configuration>
	<configSections>
		<section name="SectionA" type="TestConfig.ConfigSectionA, TestConfig" />
	</configSections>
	<SectionA>
		<elements>
			<add name="test1" value="value1" />
		</elements>
	</SectionA>
</configuration>

Noch ein Edit:
Unter Mono/Linux funktioniert es einwandfrei. Aber unter Windows/.Net nicht