Browse Source

Make Properties class thread-safe. (probably fixes forum-18390).

git-svn-id: svn://svn.sharpdevelop.net/sharpdevelop/trunk@2666 1ccf3a8d-04fe-1044-b7c0-cef0b8235c61
shortcuts
Daniel Grunwald 18 years ago
parent
commit
22816a916b
  1. 9
      src/Main/Base/Project/Src/Services/IconService.cs
  2. 196
      src/Main/Core/Project/Src/Services/PropertyService/Properties.cs

9
src/Main/Base/Project/Src/Services/IconService.cs

@ -24,15 +24,6 @@ namespace ICSharpCode.SharpDevelop @@ -24,15 +24,6 @@ namespace ICSharpCode.SharpDevelop
readonly static char[] separators = {Path.DirectorySeparatorChar, Path.VolumeSeparatorChar};
static IconService()
{
Thread myThread = new Thread(new ThreadStart(LoadThread));
myThread.Name = "IconLoader";
myThread.IsBackground = true;
myThread.Priority = ThreadPriority.Normal;
myThread.Start();
}
static void LoadThread()
{
try {
InitializeIcons(AddInTree.GetTreeNode("/Workspace/Icons"));

196
src/Main/Core/Project/Src/Services/PropertyService/Properties.cs

@ -52,69 +52,75 @@ namespace ICSharpCode.Core @@ -52,69 +52,75 @@ namespace ICSharpCode.Core
public string[] Elements
{
get
{
List<string> ret = new List<string>();
foreach (KeyValuePair<string, object> property in properties)
ret.Add(property.Key);
return ret.ToArray();
get {
lock (properties) {
List<string> ret = new List<string>();
foreach (KeyValuePair<string, object> property in properties)
ret.Add(property.Key);
return ret.ToArray();
}
}
}
public object Get(string property)
{
if (!properties.ContainsKey(property)) {
return null;
lock (properties) {
object val;
properties.TryGetValue(property, out val);
return val;
}
return properties[property];
}
public void Set<T>(string property, T value)
{
T oldValue = default(T);
if (!properties.ContainsKey(property)) {
properties.Add(property, value);
} else {
oldValue = Get<T>(property, value);
properties[property] = value;
lock (properties) {
if (!properties.ContainsKey(property)) {
properties.Add(property, value);
} else {
oldValue = Get<T>(property, value);
properties[property] = value;
}
}
OnPropertyChanged(new PropertyChangedEventArgs(this, property, oldValue, value));
}
public bool Contains(string property)
{
return properties.ContainsKey(property);
lock (properties) {
return properties.ContainsKey(property);
}
}
public int Count
{
get
{
return properties.Count;
public int Count {
get {
lock (properties) {
return properties.Count;
}
}
}
public bool Remove(string property)
{
return properties.Remove(property);
}
public Properties()
{
lock (properties) {
return properties.Remove(property);
}
}
public override string ToString()
{
StringBuilder sb = new StringBuilder();
sb.Append("[Properties:{");
foreach (KeyValuePair<string, object> entry in properties) {
sb.Append(entry.Key);
sb.Append("=");
sb.Append(entry.Value);
sb.Append(",");
lock (properties) {
StringBuilder sb = new StringBuilder();
sb.Append("[Properties:{");
foreach (KeyValuePair<string, object> entry in properties) {
sb.Append(entry.Key);
sb.Append("=");
sb.Append(entry.Value);
sb.Append(",");
}
sb.Append("}]");
return sb.ToString();
}
sb.Append("}]");
return sb.ToString();
}
public static Properties ReadFromAttributes(XmlReader reader)
@ -130,7 +136,7 @@ namespace ICSharpCode.Core @@ -130,7 +136,7 @@ namespace ICSharpCode.Core
return properties;
}
public void ReadProperties(XmlReader reader, string endElement)
internal void ReadProperties(XmlReader reader, string endElement)
{
if (reader.IsEmptyElement) {
return;
@ -182,26 +188,28 @@ namespace ICSharpCode.Core @@ -182,26 +188,28 @@ namespace ICSharpCode.Core
public void WriteProperties(XmlWriter writer)
{
foreach (KeyValuePair<string, object> entry in properties) {
object val = entry.Value;
if (val is Properties) {
writer.WriteStartElement("Properties");
writer.WriteAttributeString("name", entry.Key);
((Properties)val).WriteProperties(writer);
writer.WriteEndElement();
} else if (val is Array || val is ArrayList) {
writer.WriteStartElement("Array");
writer.WriteAttributeString("name", entry.Key);
foreach (object o in (IEnumerable)val) {
writer.WriteStartElement("Element");
WriteValue(writer, o);
lock (properties) {
foreach (KeyValuePair<string, object> entry in properties) {
object val = entry.Value;
if (val is Properties) {
writer.WriteStartElement("Properties");
writer.WriteAttributeString("name", entry.Key);
((Properties)val).WriteProperties(writer);
writer.WriteEndElement();
} else if (val is Array || val is ArrayList) {
writer.WriteStartElement("Array");
writer.WriteAttributeString("name", entry.Key);
foreach (object o in (IEnumerable)val) {
writer.WriteStartElement("Element");
WriteValue(writer, o);
writer.WriteEndElement();
}
writer.WriteEndElement();
} else {
writer.WriteStartElement(entry.Key);
WriteValue(writer, val);
writer.WriteEndElement();
}
writer.WriteEndElement();
} else {
writer.WriteStartElement(entry.Key);
WriteValue(writer, val);
writer.WriteEndElement();
}
}
}
@ -259,52 +267,54 @@ namespace ICSharpCode.Core @@ -259,52 +267,54 @@ namespace ICSharpCode.Core
public T Get<T>(string property, T defaultValue)
{
if (!properties.ContainsKey(property)) {
properties.Add(property, defaultValue);
return defaultValue;
}
object o = properties[property];
if (o is string && typeof(T) != typeof(string)) {
TypeConverter c = TypeDescriptor.GetConverter(typeof(T));
try {
o = c.ConvertFromInvariantString(o.ToString());
} catch (Exception ex) {
MessageService.ShowWarning("Error loading property '" + property + "': " + ex.Message);
o = defaultValue;
lock (properties) {
object o;
if (!properties.TryGetValue(property, out o)) {
properties.Add(property, defaultValue);
return defaultValue;
}
properties[property] = o; // store for future look up
} else if (o is ArrayList && typeof(T).IsArray) {
ArrayList list = (ArrayList)o;
Type elementType = typeof(T).GetElementType();
Array arr = System.Array.CreateInstance(elementType, list.Count);
TypeConverter c = TypeDescriptor.GetConverter(elementType);
try {
for (int i = 0; i < arr.Length; ++i) {
if (list[i] != null) {
arr.SetValue(c.ConvertFromInvariantString(list[i].ToString()), i);
if (o is string && typeof(T) != typeof(string)) {
TypeConverter c = TypeDescriptor.GetConverter(typeof(T));
try {
o = c.ConvertFromInvariantString(o.ToString());
} catch (Exception ex) {
MessageService.ShowWarning("Error loading property '" + property + "': " + ex.Message);
o = defaultValue;
}
properties[property] = o; // store for future look up
} else if (o is ArrayList && typeof(T).IsArray) {
ArrayList list = (ArrayList)o;
Type elementType = typeof(T).GetElementType();
Array arr = System.Array.CreateInstance(elementType, list.Count);
TypeConverter c = TypeDescriptor.GetConverter(elementType);
try {
for (int i = 0; i < arr.Length; ++i) {
if (list[i] != null) {
arr.SetValue(c.ConvertFromInvariantString(list[i].ToString()), i);
}
}
o = arr;
} catch (Exception ex) {
MessageService.ShowWarning("Error loading property '" + property + "': " + ex.Message);
o = defaultValue;
}
properties[property] = o; // store for future look up
} else if (!(o is string) && typeof(T) == typeof(string)) {
TypeConverter c = TypeDescriptor.GetConverter(typeof(T));
if (c.CanConvertTo(typeof(string))) {
o = c.ConvertToInvariantString(o);
} else {
o = o.ToString();
}
o = arr;
} catch (Exception ex) {
MessageService.ShowWarning("Error loading property '" + property + "': " + ex.Message);
o = defaultValue;
}
properties[property] = o; // store for future look up
} else if (!(o is string) && typeof(T) == typeof(string)) {
TypeConverter c = TypeDescriptor.GetConverter(typeof(T));
if (c.CanConvertTo(typeof(string))) {
o = c.ConvertToInvariantString(o);
} else {
o = o.ToString();
try {
return (T)o;
} catch (NullReferenceException) {
// can happen when configuration is invalid -> o is null and a value type is expected
return defaultValue;
}
}
try {
return (T)o;
} catch (NullReferenceException) {
// can happen when configuration is invalid -> o is null and a value type is expected
return defaultValue;
}
}
protected virtual void OnPropertyChanged(PropertyChangedEventArgs e)

Loading…
Cancel
Save