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 19 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
readonly static char[] separators = {Path.DirectorySeparatorChar, Path.VolumeSeparatorChar}; readonly static char[] separators = {Path.DirectorySeparatorChar, Path.VolumeSeparatorChar};
static IconService() 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 { try {
InitializeIcons(AddInTree.GetTreeNode("/Workspace/Icons")); InitializeIcons(AddInTree.GetTreeNode("/Workspace/Icons"));

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

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

Loading…
Cancel
Save