mirror of
https://github.com/ClemensFischer/XAML-Map-Control.git
synced 2025-12-06 07:12:04 +01:00
Minor code improvements
This commit is contained in:
parent
6b25260536
commit
472658a6d9
|
|
@ -1,5 +1,6 @@
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
using System.Collections.Specialized;
|
||||||
using System.Diagnostics;
|
using System.Diagnostics;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
using System.Runtime.Caching;
|
using System.Runtime.Caching;
|
||||||
|
|
@ -18,25 +19,61 @@ namespace Caching
|
||||||
private const string expiresField = "Expires";
|
private const string expiresField = "Expires";
|
||||||
|
|
||||||
private readonly BinaryFormatter formatter = new BinaryFormatter();
|
private readonly BinaryFormatter formatter = new BinaryFormatter();
|
||||||
private readonly FileDb fileDb = new FileDb();
|
private readonly FileDb fileDb = new FileDb { AutoFlush = false, AutoCleanThreshold = -1 };
|
||||||
private readonly string name;
|
private readonly string name;
|
||||||
private readonly string path;
|
private readonly string path;
|
||||||
|
|
||||||
public FileDbCache(string name, string path)
|
public FileDbCache(string name, NameValueCollection config)
|
||||||
|
: this(name, config["directory"])
|
||||||
{
|
{
|
||||||
if (string.IsNullOrEmpty(path))
|
string autoFlush = config["autoFlush"];
|
||||||
|
string autoCleanThreshold = config["autoCleanThreshold"];
|
||||||
|
|
||||||
|
if (autoFlush != null)
|
||||||
{
|
{
|
||||||
throw new ArgumentException("The parameter path must not be null or empty.");
|
try
|
||||||
|
{
|
||||||
|
fileDb.AutoFlush = bool.Parse(autoFlush);
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
throw new ArgumentException("The configuration parameter autoFlush must be a boolean value.", ex);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (autoCleanThreshold != null)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
fileDb.AutoCleanThreshold = int.Parse(autoCleanThreshold);
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
throw new ArgumentException("The configuration parameter autoCleanThreshold must be an integer value.", ex);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public FileDbCache(string name, string directory)
|
||||||
|
{
|
||||||
|
if (string.IsNullOrEmpty(name))
|
||||||
|
{
|
||||||
|
throw new ArgumentException("The parameter name must not be null or empty.");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (string.IsNullOrEmpty(directory))
|
||||||
|
{
|
||||||
|
throw new ArgumentException("The parameter directory must not be null or empty.");
|
||||||
|
}
|
||||||
|
|
||||||
|
this.name = name;
|
||||||
|
path = Path.Combine(directory, name);
|
||||||
|
|
||||||
if (string.IsNullOrEmpty(Path.GetExtension(path)))
|
if (string.IsNullOrEmpty(Path.GetExtension(path)))
|
||||||
{
|
{
|
||||||
path += ".fdb";
|
path += ".fdb";
|
||||||
}
|
}
|
||||||
|
|
||||||
this.name = name;
|
|
||||||
this.path = path;
|
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
fileDb.Open(path, false);
|
fileDb.Open(path, false);
|
||||||
|
|
@ -46,7 +83,7 @@ namespace Caching
|
||||||
CreateDatebase();
|
CreateDatebase();
|
||||||
}
|
}
|
||||||
|
|
||||||
Trace.TraceInformation("FileDbCache created with {0} cached items", fileDb.NumRecords);
|
Trace.TraceInformation("FileDbCache: Opened database with {0} cached items in {1}", fileDb.NumRecords, path);
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool AutoFlush
|
public bool AutoFlush
|
||||||
|
|
@ -96,21 +133,24 @@ namespace Caching
|
||||||
|
|
||||||
long count = 0;
|
long count = 0;
|
||||||
|
|
||||||
try
|
if (fileDb.IsOpen)
|
||||||
{
|
{
|
||||||
count = fileDb.NumRecords;
|
try
|
||||||
}
|
|
||||||
catch
|
|
||||||
{
|
|
||||||
if (CheckReindex())
|
|
||||||
{
|
{
|
||||||
|
count = fileDb.NumRecords;
|
||||||
|
}
|
||||||
|
catch (Exception ex1)
|
||||||
|
{
|
||||||
|
Trace.TraceWarning("FileDbCache: FileDb.NumRecords failed: {0}", ex1.Message);
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
|
fileDb.Reindex();
|
||||||
count = fileDb.NumRecords;
|
count = fileDb.NumRecords;
|
||||||
}
|
}
|
||||||
catch
|
catch (Exception ex2)
|
||||||
{
|
{
|
||||||
CreateDatebase();
|
Trace.TraceWarning("FileDbCache: FileDb.Reindex() failed: {0}", ex2.Message);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -118,75 +158,64 @@ namespace Caching
|
||||||
return count;
|
return count;
|
||||||
}
|
}
|
||||||
|
|
||||||
public override bool Contains(string key, string regionName = null)
|
private Record GetRecord(string key)
|
||||||
{
|
{
|
||||||
if (regionName != null)
|
Record record = null;
|
||||||
|
|
||||||
|
if (fileDb.IsOpen)
|
||||||
{
|
{
|
||||||
throw new NotSupportedException("The parameter regionName must be null.");
|
try
|
||||||
|
{
|
||||||
|
record = fileDb.GetRecordByKey(key, new string[] { valueField }, false);
|
||||||
|
}
|
||||||
|
catch (Exception ex1)
|
||||||
|
{
|
||||||
|
Trace.TraceWarning("FileDbCache: FileDb.GetRecordByKey(\"{0}\") failed: {1}", key, ex1.Message);
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
fileDb.Reindex();
|
||||||
|
record = fileDb.GetRecordByKey(key, new string[] { valueField }, false);
|
||||||
|
}
|
||||||
|
catch (Exception ex2)
|
||||||
|
{
|
||||||
|
Trace.TraceWarning("FileDbCache: FileDb.Reindex() failed: {0}", ex2.Message);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return record;
|
||||||
|
}
|
||||||
|
|
||||||
|
public override bool Contains(string key, string regionName = null)
|
||||||
|
{
|
||||||
if (key == null)
|
if (key == null)
|
||||||
{
|
{
|
||||||
throw new ArgumentNullException("The parameter key must not be null.");
|
throw new ArgumentNullException("The parameter key must not be null.");
|
||||||
}
|
}
|
||||||
|
|
||||||
bool contains = false;
|
if (regionName != null)
|
||||||
|
|
||||||
try
|
|
||||||
{
|
{
|
||||||
contains = fileDb.GetRecordByKey(key, new string[0], false) != null;
|
throw new NotSupportedException("The parameter regionName must be null.");
|
||||||
}
|
|
||||||
catch
|
|
||||||
{
|
|
||||||
if (CheckReindex())
|
|
||||||
{
|
|
||||||
try
|
|
||||||
{
|
|
||||||
contains = fileDb.GetRecordByKey(key, new string[0], false) != null;
|
|
||||||
}
|
|
||||||
catch
|
|
||||||
{
|
|
||||||
CreateDatebase();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return contains;
|
return GetRecord(key) != null;
|
||||||
}
|
}
|
||||||
|
|
||||||
public override object Get(string key, string regionName = null)
|
public override object Get(string key, string regionName = null)
|
||||||
{
|
{
|
||||||
if (regionName != null)
|
|
||||||
{
|
|
||||||
throw new NotSupportedException("The parameter regionName must be null.");
|
|
||||||
}
|
|
||||||
|
|
||||||
if (key == null)
|
if (key == null)
|
||||||
{
|
{
|
||||||
throw new ArgumentNullException("The parameter key must not be null.");
|
throw new ArgumentNullException("The parameter key must not be null.");
|
||||||
}
|
}
|
||||||
|
|
||||||
object value = null;
|
if (regionName != null)
|
||||||
Record record = null;
|
{
|
||||||
|
throw new NotSupportedException("The parameter regionName must be null.");
|
||||||
|
}
|
||||||
|
|
||||||
try
|
object value = null;
|
||||||
{
|
Record record = GetRecord(key);
|
||||||
record = fileDb.GetRecordByKey(key, new string[] { valueField }, false);
|
|
||||||
}
|
|
||||||
catch
|
|
||||||
{
|
|
||||||
if (CheckReindex())
|
|
||||||
{
|
|
||||||
try
|
|
||||||
{
|
|
||||||
record = fileDb.GetRecordByKey(key, new string[] { valueField }, false);
|
|
||||||
}
|
|
||||||
catch
|
|
||||||
{
|
|
||||||
CreateDatebase();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (record != null)
|
if (record != null)
|
||||||
{
|
{
|
||||||
|
|
@ -197,16 +226,17 @@ namespace Caching
|
||||||
value = formatter.Deserialize(stream);
|
value = formatter.Deserialize(stream);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
catch (Exception exc)
|
catch (Exception ex1)
|
||||||
{
|
{
|
||||||
Trace.TraceWarning("FileDbCache.Get({0}): {1}", key, exc.Message);
|
Trace.TraceWarning("FileDbCache: Failed deserializing item \"{0}\": {1}", key, ex1.Message);
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
fileDb.DeleteRecordByKey(key);
|
fileDb.DeleteRecordByKey(key);
|
||||||
}
|
}
|
||||||
catch
|
catch (Exception ex2)
|
||||||
{
|
{
|
||||||
|
Trace.TraceWarning("FileDbCache: FileDb.DeleteRecordByKey(\"{0}\") failed: {1}", key, ex2.Message);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -239,9 +269,9 @@ namespace Caching
|
||||||
|
|
||||||
public override void Set(string key, object value, CacheItemPolicy policy, string regionName = null)
|
public override void Set(string key, object value, CacheItemPolicy policy, string regionName = null)
|
||||||
{
|
{
|
||||||
if (regionName != null)
|
if (key == null)
|
||||||
{
|
{
|
||||||
throw new NotSupportedException("The parameter regionName must be null.");
|
throw new ArgumentNullException("The parameter key must not be null.");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (value == null)
|
if (value == null)
|
||||||
|
|
@ -249,53 +279,57 @@ namespace Caching
|
||||||
throw new ArgumentNullException("The parameter value must not be null.");
|
throw new ArgumentNullException("The parameter value must not be null.");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (key == null)
|
if (regionName != null)
|
||||||
{
|
{
|
||||||
throw new ArgumentNullException("The parameter key must not be null.");
|
throw new NotSupportedException("The parameter regionName must be null.");
|
||||||
}
|
}
|
||||||
|
|
||||||
byte[] valueBuffer = null;
|
if (fileDb.IsOpen)
|
||||||
|
|
||||||
try
|
|
||||||
{
|
{
|
||||||
using (MemoryStream stream = new MemoryStream())
|
byte[] valueBuffer = null;
|
||||||
{
|
|
||||||
formatter.Serialize(stream, value);
|
|
||||||
valueBuffer = stream.ToArray();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
catch (Exception exc)
|
|
||||||
{
|
|
||||||
Trace.TraceWarning("FileDbCache.Set({0}): {1}", key, exc.Message);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (valueBuffer != null)
|
|
||||||
{
|
|
||||||
DateTime expires = DateTime.MaxValue;
|
|
||||||
|
|
||||||
if (policy.AbsoluteExpiration != InfiniteAbsoluteExpiration)
|
|
||||||
{
|
|
||||||
expires = policy.AbsoluteExpiration.DateTime;
|
|
||||||
}
|
|
||||||
else if (policy.SlidingExpiration != NoSlidingExpiration)
|
|
||||||
{
|
|
||||||
expires = DateTime.UtcNow + policy.SlidingExpiration;
|
|
||||||
}
|
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
AddOrUpdateRecord(key, valueBuffer, expires);
|
using (MemoryStream stream = new MemoryStream())
|
||||||
}
|
|
||||||
catch
|
|
||||||
{
|
|
||||||
if (CheckReindex())
|
|
||||||
{
|
{
|
||||||
|
formatter.Serialize(stream, value);
|
||||||
|
valueBuffer = stream.ToArray();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
Trace.TraceWarning("FileDbCache: Failed serializing item \"{0}\": {1}", key, ex.Message);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (valueBuffer != null)
|
||||||
|
{
|
||||||
|
DateTime expires = DateTime.MaxValue;
|
||||||
|
|
||||||
|
if (policy.AbsoluteExpiration != InfiniteAbsoluteExpiration)
|
||||||
|
{
|
||||||
|
expires = policy.AbsoluteExpiration.DateTime;
|
||||||
|
}
|
||||||
|
else if (policy.SlidingExpiration != NoSlidingExpiration)
|
||||||
|
{
|
||||||
|
expires = DateTime.UtcNow + policy.SlidingExpiration;
|
||||||
|
}
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
AddOrUpdateRecord(key, valueBuffer, expires);
|
||||||
|
}
|
||||||
|
catch (Exception ex1)
|
||||||
|
{
|
||||||
|
Trace.TraceWarning("FileDbCache: FileDb.UpdateRecordByKey(\"{0}\") failed: {1}", key, ex1.Message);
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
|
fileDb.Reindex();
|
||||||
AddOrUpdateRecord(key, valueBuffer, expires);
|
AddOrUpdateRecord(key, valueBuffer, expires);
|
||||||
}
|
}
|
||||||
catch
|
catch (Exception ex2)
|
||||||
{
|
{
|
||||||
|
Trace.TraceWarning("FileDbCache: FileDb.Reindex() failed: {0}, creating new database", ex2.Message);
|
||||||
CreateDatebase();
|
CreateDatebase();
|
||||||
AddOrUpdateRecord(key, valueBuffer, expires);
|
AddOrUpdateRecord(key, valueBuffer, expires);
|
||||||
}
|
}
|
||||||
|
|
@ -343,8 +377,9 @@ namespace Caching
|
||||||
{
|
{
|
||||||
fileDb.DeleteRecordByKey(key);
|
fileDb.DeleteRecordByKey(key);
|
||||||
}
|
}
|
||||||
catch
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
|
Trace.TraceWarning("FileDbCache: FileDb.DeleteRecordByKey(\"{0}\") failed: {1}", key, ex.Message);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -357,9 +392,9 @@ namespace Caching
|
||||||
{
|
{
|
||||||
fileDb.Flush();
|
fileDb.Flush();
|
||||||
}
|
}
|
||||||
catch
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
CheckReindex();
|
Trace.TraceWarning("FileDbCache: FileDb.Flush() failed: {0}", ex.Message);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -369,40 +404,29 @@ namespace Caching
|
||||||
{
|
{
|
||||||
fileDb.Clean();
|
fileDb.Clean();
|
||||||
}
|
}
|
||||||
catch
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
CheckReindex();
|
Trace.TraceWarning("FileDbCache: FileDb.Clean() failed: {0}", ex.Message);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Dispose()
|
public void Dispose()
|
||||||
{
|
|
||||||
try
|
|
||||||
{
|
|
||||||
fileDb.DeleteRecords(new FilterExpression(expiresField, DateTime.UtcNow, EqualityEnum.LessThanOrEqual));
|
|
||||||
Trace.TraceInformation("FileDbCache has deleted {0} expired items", fileDb.NumDeleted);
|
|
||||||
fileDb.Clean();
|
|
||||||
fileDb.Close();
|
|
||||||
}
|
|
||||||
catch
|
|
||||||
{
|
|
||||||
if (CheckReindex())
|
|
||||||
{
|
|
||||||
fileDb.Close();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private bool CheckReindex()
|
|
||||||
{
|
{
|
||||||
if (fileDb.IsOpen)
|
if (fileDb.IsOpen)
|
||||||
{
|
{
|
||||||
Trace.TraceWarning("FileDbCache is reindexing the cache database");
|
try
|
||||||
fileDb.Reindex();
|
{
|
||||||
return true;
|
fileDb.DeleteRecords(new FilterExpression(expiresField, DateTime.UtcNow, EqualityEnum.LessThanOrEqual));
|
||||||
}
|
Trace.TraceInformation("FileDbCache: Deleting {0} expired items", fileDb.NumDeleted);
|
||||||
|
fileDb.Clean();
|
||||||
|
}
|
||||||
|
catch
|
||||||
|
{
|
||||||
|
fileDb.Reindex();
|
||||||
|
}
|
||||||
|
|
||||||
return false;
|
fileDb.Close();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void CreateDatebase()
|
private void CreateDatebase()
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,8 @@
|
||||||
using System;
|
// WPF MapControl - http://wpfmapcontrol.codeplex.com/
|
||||||
|
// Copyright © 2012 Clemens Fischer
|
||||||
|
// Licensed under the Microsoft Public License (Ms-PL)
|
||||||
|
|
||||||
|
using System;
|
||||||
using System.ComponentModel;
|
using System.ComponentModel;
|
||||||
using System.Globalization;
|
using System.Globalization;
|
||||||
using System.Windows;
|
using System.Windows;
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,8 @@
|
||||||
using System;
|
// WPF MapControl - http://wpfmapcontrol.codeplex.com/
|
||||||
|
// Copyright © 2012 Clemens Fischer
|
||||||
|
// Licensed under the Microsoft Public License (Ms-PL)
|
||||||
|
|
||||||
|
using System;
|
||||||
using System.Windows;
|
using System.Windows;
|
||||||
using System.Windows.Media.Animation;
|
using System.Windows.Media.Animation;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,8 @@
|
||||||
using System;
|
// WPF MapControl - http://wpfmapcontrol.codeplex.com/
|
||||||
|
// Copyright © 2012 Clemens Fischer
|
||||||
|
// Licensed under the Microsoft Public License (Ms-PL)
|
||||||
|
|
||||||
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Collections.ObjectModel;
|
using System.Collections.ObjectModel;
|
||||||
using System.ComponentModel;
|
using System.ComponentModel;
|
||||||
|
|
|
||||||
|
|
@ -2,12 +2,10 @@
|
||||||
// Copyright © 2012 Clemens Fischer
|
// Copyright © 2012 Clemens Fischer
|
||||||
// Licensed under the Microsoft Public License (Ms-PL)
|
// Licensed under the Microsoft Public License (Ms-PL)
|
||||||
|
|
||||||
using System;
|
|
||||||
using System.Windows;
|
using System.Windows;
|
||||||
using System.Windows.Controls;
|
using System.Windows.Controls;
|
||||||
using System.Windows.Controls.Primitives;
|
using System.Windows.Controls.Primitives;
|
||||||
using System.Windows.Input;
|
using System.Windows.Input;
|
||||||
using System.Windows.Media;
|
|
||||||
|
|
||||||
namespace MapControl
|
namespace MapControl
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -5,7 +5,6 @@
|
||||||
using System;
|
using System;
|
||||||
using System.Windows;
|
using System.Windows;
|
||||||
using System.Windows.Controls;
|
using System.Windows.Controls;
|
||||||
using System.Windows.Media;
|
|
||||||
|
|
||||||
namespace MapControl
|
namespace MapControl
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -2,7 +2,6 @@
|
||||||
// Copyright © 2012 Clemens Fischer
|
// Copyright © 2012 Clemens Fischer
|
||||||
// Licensed under the Microsoft Public License (Ms-PL)
|
// Licensed under the Microsoft Public License (Ms-PL)
|
||||||
|
|
||||||
using System;
|
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Windows;
|
using System.Windows;
|
||||||
|
|
|
||||||
|
|
@ -4,7 +4,6 @@
|
||||||
|
|
||||||
using System;
|
using System;
|
||||||
using System.Windows;
|
using System.Windows;
|
||||||
using System.Windows.Media;
|
|
||||||
|
|
||||||
namespace MapControl
|
namespace MapControl
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,7 @@
|
||||||
using System;
|
// WPF MapControl - http://wpfmapcontrol.codeplex.com/
|
||||||
|
// Copyright © 2012 Clemens Fischer
|
||||||
|
// Licensed under the Microsoft Public License (Ms-PL)
|
||||||
|
|
||||||
using System.Windows;
|
using System.Windows;
|
||||||
using System.Windows.Controls;
|
using System.Windows.Controls;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -3,12 +3,11 @@
|
||||||
// Licensed under the Microsoft Public License (Ms-PL)
|
// Licensed under the Microsoft Public License (Ms-PL)
|
||||||
|
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections;
|
||||||
using System.Collections.Specialized;
|
using System.Collections.Specialized;
|
||||||
using System.Windows;
|
using System.Windows;
|
||||||
using System.Windows.Media;
|
using System.Windows.Media;
|
||||||
using System.Windows.Threading;
|
using System.Windows.Threading;
|
||||||
using System.Collections;
|
|
||||||
|
|
||||||
namespace MapControl
|
namespace MapControl
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -4,6 +4,7 @@
|
||||||
|
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
using System.Collections.Specialized;
|
||||||
using System.Diagnostics;
|
using System.Diagnostics;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
|
|
@ -11,7 +12,6 @@ using System.Net;
|
||||||
using System.Runtime.Caching;
|
using System.Runtime.Caching;
|
||||||
using System.Threading;
|
using System.Threading;
|
||||||
using System.Windows;
|
using System.Windows;
|
||||||
using System.Windows.Media;
|
|
||||||
using System.Windows.Media.Imaging;
|
using System.Windows.Media.Imaging;
|
||||||
using System.Windows.Threading;
|
using System.Windows.Threading;
|
||||||
|
|
||||||
|
|
@ -48,19 +48,52 @@ namespace MapControl
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The time interval after which cached images expire. The default value is 30 days.
|
/// The time interval after which cached images expire. The default value is 30 days.
|
||||||
/// When an image is not retrieved from the cache during this interval it is considered
|
/// When an image is not retrieved from the cache during this interval it is considered
|
||||||
/// as expired and will be removed from the cache. If an image is retrieved from the cache
|
/// as expired and will be removed from the cache. If an image is retrieved from the
|
||||||
/// and the CacheUpdateAge time interval has expired, the image is downloaded again and
|
/// cache and the CacheUpdateAge time interval has expired, the image is downloaded
|
||||||
/// rewritten to the cache with new expiration time.
|
/// again and rewritten to the cache with a new expiration time.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public static TimeSpan CacheExpiration { get; set; }
|
public static TimeSpan CacheExpiration { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The time interval after which a cached image is updated and rewritten to the cache.
|
/// The time interval after which a cached image is updated and rewritten to the cache.
|
||||||
/// The default value is one day. This time interval should be shorter than the value of
|
/// The default value is one day. This time interval should be shorter than the value
|
||||||
/// the CacheExpiration property.
|
/// of the CacheExpiration property.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public static TimeSpan CacheUpdateAge { get; set; }
|
public static TimeSpan CacheUpdateAge { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Creates an instance of the ObjectCache-derived type T and sets the static Cache
|
||||||
|
/// property to this instance. Class T must (like System.Runtime.Caching.MemoryCache)
|
||||||
|
/// provide a constructor with two parameters, first a string that gets the name of
|
||||||
|
/// the cache instance, second a NameValueCollection that gets the config parameter.
|
||||||
|
/// If config is null, a new NameValueCollection is created. If config does not already
|
||||||
|
/// contain an entry with key "directory", a new entry is added with this key and a
|
||||||
|
/// value that specifies the path to an application data directory where the cache
|
||||||
|
/// implementation may store persistent cache data files.
|
||||||
|
/// </summary>
|
||||||
|
public static void CreateCache<T>(NameValueCollection config = null) where T : ObjectCache
|
||||||
|
{
|
||||||
|
if (config == null)
|
||||||
|
{
|
||||||
|
config = new NameValueCollection(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (config["directory"] == null)
|
||||||
|
{
|
||||||
|
config["directory"] = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.CommonApplicationData), "MapControl");
|
||||||
|
}
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
Cache = (ObjectCache)Activator.CreateInstance(typeof(T), "TileCache", config);
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
Trace.TraceWarning("Could not create instance of type {0} with String and NameValueCollection constructor parameters: {1}", typeof(T), ex.Message);
|
||||||
|
throw;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static TileImageLoader()
|
static TileImageLoader()
|
||||||
{
|
{
|
||||||
Cache = MemoryCache.Default;
|
Cache = MemoryCache.Default;
|
||||||
|
|
@ -77,7 +110,7 @@ namespace MapControl
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
public TileImageLoader(TileLayer tileLayer)
|
internal TileImageLoader(TileLayer tileLayer)
|
||||||
{
|
{
|
||||||
this.tileLayer = tileLayer;
|
this.tileLayer = tileLayer;
|
||||||
}
|
}
|
||||||
|
|
@ -128,7 +161,7 @@ namespace MapControl
|
||||||
}
|
}
|
||||||
else if (!CreateTileImage(tile, cachedImage.ImageBuffer))
|
else if (!CreateTileImage(tile, cachedImage.ImageBuffer))
|
||||||
{
|
{
|
||||||
// got garbage from cache
|
// got corrupted buffer from cache
|
||||||
Cache.Remove(key);
|
Cache.Remove(key);
|
||||||
pendingTiles.Enqueue(tile);
|
pendingTiles.Enqueue(tile);
|
||||||
}
|
}
|
||||||
|
|
@ -215,28 +248,28 @@ namespace MapControl
|
||||||
|
|
||||||
TraceInformation("{0} - Completed", tile.Uri);
|
TraceInformation("{0} - Completed", tile.Uri);
|
||||||
}
|
}
|
||||||
catch (WebException exc)
|
catch (WebException ex)
|
||||||
{
|
{
|
||||||
buffer = null;
|
buffer = null;
|
||||||
|
|
||||||
if (exc.Status == WebExceptionStatus.ProtocolError)
|
if (ex.Status == WebExceptionStatus.ProtocolError)
|
||||||
{
|
{
|
||||||
TraceInformation("{0} - {1}", tile.Uri, ((HttpWebResponse)exc.Response).StatusCode);
|
TraceInformation("{0} - {1}", tile.Uri, ((HttpWebResponse)ex.Response).StatusCode);
|
||||||
}
|
}
|
||||||
else if (exc.Status == WebExceptionStatus.RequestCanceled) // by HttpWebRequest.Abort in CancelDownloadTiles
|
else if (ex.Status == WebExceptionStatus.RequestCanceled) // by HttpWebRequest.Abort in CancelDownloadTiles
|
||||||
{
|
{
|
||||||
TraceInformation("{0} - {1}", tile.Uri, exc.Status);
|
TraceInformation("{0} - {1}", tile.Uri, ex.Status);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
TraceWarning("{0} - {1}", tile.Uri, exc.Status);
|
TraceWarning("{0} - {1}", tile.Uri, ex.Status);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
catch (Exception exc)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
buffer = null;
|
buffer = null;
|
||||||
|
|
||||||
TraceWarning("{0} - {1}", tile.Uri, exc.Message);
|
TraceWarning("{0} - {1}", tile.Uri, ex.Message);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (request != null)
|
if (request != null)
|
||||||
|
|
@ -267,9 +300,9 @@ namespace MapControl
|
||||||
|
|
||||||
Dispatcher.BeginInvoke((Action)(() => tile.Image = bitmap));
|
Dispatcher.BeginInvoke((Action)(() => tile.Image = bitmap));
|
||||||
}
|
}
|
||||||
catch (Exception exc)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
TraceWarning("Creating tile image failed: {0}", exc.Message);
|
TraceWarning("Creating tile image failed: {0}", ex.Message);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -4,7 +4,6 @@
|
||||||
|
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
|
||||||
using System.Windows;
|
using System.Windows;
|
||||||
using System.Windows.Markup;
|
using System.Windows.Markup;
|
||||||
using System.Windows.Media;
|
using System.Windows.Media;
|
||||||
|
|
|
||||||
|
|
@ -2,9 +2,7 @@
|
||||||
// Copyright © 2012 Clemens Fischer
|
// Copyright © 2012 Clemens Fischer
|
||||||
// Licensed under the Microsoft Public License (Ms-PL)
|
// Licensed under the Microsoft Public License (Ms-PL)
|
||||||
|
|
||||||
using System;
|
|
||||||
using System.Collections.ObjectModel;
|
using System.Collections.ObjectModel;
|
||||||
using System.Windows.Media;
|
|
||||||
|
|
||||||
namespace MapControl
|
namespace MapControl
|
||||||
{
|
{
|
||||||
|
|
|
||||||
15
SampleApps/SampleApplication/App.config
Normal file
15
SampleApps/SampleApplication/App.config
Normal file
|
|
@ -0,0 +1,15 @@
|
||||||
|
<?xml version="1.0" encoding="utf-8" ?>
|
||||||
|
<configuration>
|
||||||
|
<configSections>
|
||||||
|
<sectionGroup name="applicationSettings" type="System.Configuration.ApplicationSettingsGroup, System, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" >
|
||||||
|
<section name="SampleApplication.Properties.Settings" type="System.Configuration.ClientSettingsSection, System, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" requirePermission="false" />
|
||||||
|
</sectionGroup>
|
||||||
|
</configSections>
|
||||||
|
<applicationSettings>
|
||||||
|
<SampleApplication.Properties.Settings>
|
||||||
|
<setting name="UsePersistentCache" serializeAs="String">
|
||||||
|
<value>True</value>
|
||||||
|
</setting>
|
||||||
|
</SampleApplication.Properties.Settings>
|
||||||
|
</applicationSettings>
|
||||||
|
</configuration>
|
||||||
|
|
@ -1,13 +1,9 @@
|
||||||
using System;
|
using System.Collections.Generic;
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.IO;
|
|
||||||
using System.Linq;
|
|
||||||
using System.Windows;
|
using System.Windows;
|
||||||
using System.Windows.Controls;
|
using System.Windows.Controls;
|
||||||
using System.Windows.Input;
|
using System.Windows.Input;
|
||||||
using System.Windows.Media;
|
|
||||||
using MapControl;
|
|
||||||
using Caching;
|
using Caching;
|
||||||
|
using MapControl;
|
||||||
|
|
||||||
namespace SampleApplication
|
namespace SampleApplication
|
||||||
{
|
{
|
||||||
|
|
@ -15,13 +11,9 @@ namespace SampleApplication
|
||||||
{
|
{
|
||||||
public MainWindow()
|
public MainWindow()
|
||||||
{
|
{
|
||||||
bool usePersistentCache = false;
|
if (Properties.Settings.Default.UsePersistentCache)
|
||||||
|
|
||||||
if (usePersistentCache)
|
|
||||||
{
|
{
|
||||||
string appDataFolder = Environment.GetFolderPath(Environment.SpecialFolder.CommonApplicationData);
|
TileImageLoader.CreateCache<FileDbCache>();
|
||||||
string cachePath = Path.Combine(appDataFolder, "MapControl", "Cache.fdb");
|
|
||||||
TileImageLoader.Cache = new FileDbCache("MapControlCache", cachePath) { AutoFlush = false };
|
|
||||||
}
|
}
|
||||||
|
|
||||||
InitializeComponent();
|
InitializeComponent();
|
||||||
|
|
|
||||||
35
SampleApps/SampleApplication/Properties/Settings.Designer.cs
generated
Normal file
35
SampleApps/SampleApplication/Properties/Settings.Designer.cs
generated
Normal file
|
|
@ -0,0 +1,35 @@
|
||||||
|
//------------------------------------------------------------------------------
|
||||||
|
// <auto-generated>
|
||||||
|
// This code was generated by a tool.
|
||||||
|
// Runtime Version:4.0.30319.225
|
||||||
|
//
|
||||||
|
// Changes to this file may cause incorrect behavior and will be lost if
|
||||||
|
// the code is regenerated.
|
||||||
|
// </auto-generated>
|
||||||
|
//------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
namespace SampleApplication.Properties {
|
||||||
|
|
||||||
|
|
||||||
|
[global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
|
||||||
|
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "10.0.0.0")]
|
||||||
|
internal sealed partial class Settings : global::System.Configuration.ApplicationSettingsBase {
|
||||||
|
|
||||||
|
private static Settings defaultInstance = ((Settings)(global::System.Configuration.ApplicationSettingsBase.Synchronized(new Settings())));
|
||||||
|
|
||||||
|
public static Settings Default {
|
||||||
|
get {
|
||||||
|
return defaultInstance;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
[global::System.Configuration.ApplicationScopedSettingAttribute()]
|
||||||
|
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
|
||||||
|
[global::System.Configuration.DefaultSettingValueAttribute("True")]
|
||||||
|
public bool UsePersistentCache {
|
||||||
|
get {
|
||||||
|
return ((bool)(this["UsePersistentCache"]));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,9 @@
|
||||||
|
<?xml version='1.0' encoding='utf-8'?>
|
||||||
|
<SettingsFile xmlns="http://schemas.microsoft.com/VisualStudio/2004/01/settings" CurrentProfile="(Default)" GeneratedClassNamespace="SampleApplication.Properties" GeneratedClassName="Settings">
|
||||||
|
<Profiles />
|
||||||
|
<Settings>
|
||||||
|
<Setting Name="UsePersistentCache" Type="System.Boolean" Scope="Application">
|
||||||
|
<Value Profile="(Default)">True</Value>
|
||||||
|
</Setting>
|
||||||
|
</Settings>
|
||||||
|
</SettingsFile>
|
||||||
|
|
@ -54,6 +54,11 @@
|
||||||
<Generator>MSBuild:Compile</Generator>
|
<Generator>MSBuild:Compile</Generator>
|
||||||
<SubType>Designer</SubType>
|
<SubType>Designer</SubType>
|
||||||
</ApplicationDefinition>
|
</ApplicationDefinition>
|
||||||
|
<Compile Include="Properties\Settings.Designer.cs">
|
||||||
|
<AutoGen>True</AutoGen>
|
||||||
|
<DesignTimeSharedInput>True</DesignTimeSharedInput>
|
||||||
|
<DependentUpon>Settings.settings</DependentUpon>
|
||||||
|
</Compile>
|
||||||
<Compile Include="SampleItems.cs" />
|
<Compile Include="SampleItems.cs" />
|
||||||
<Page Include="MainWindow.xaml">
|
<Page Include="MainWindow.xaml">
|
||||||
<Generator>MSBuild:Compile</Generator>
|
<Generator>MSBuild:Compile</Generator>
|
||||||
|
|
@ -84,6 +89,13 @@
|
||||||
<Name>MapControl</Name>
|
<Name>MapControl</Name>
|
||||||
</ProjectReference>
|
</ProjectReference>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<None Include="App.config" />
|
||||||
|
<None Include="Properties\Settings.settings">
|
||||||
|
<Generator>SettingsSingleFileGenerator</Generator>
|
||||||
|
<LastGenOutput>Settings.Designer.cs</LastGenOutput>
|
||||||
|
</None>
|
||||||
|
</ItemGroup>
|
||||||
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
|
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
|
||||||
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
|
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
|
||||||
Other similar extension points exist, see Microsoft.Common.targets.
|
Other similar extension points exist, see Microsoft.Common.targets.
|
||||||
|
|
|
||||||
|
|
@ -9,7 +9,7 @@ using System.Runtime.InteropServices;
|
||||||
// set of attributes. Change these attribute values to modify the information
|
// set of attributes. Change these attribute values to modify the information
|
||||||
// associated with an assembly.
|
// associated with an assembly.
|
||||||
[assembly: AssemblyTitle("SurfaceApplication")]
|
[assembly: AssemblyTitle("SurfaceApplication")]
|
||||||
[assembly: AssemblyDescription("WPF Map Control Sample SurfaceApplication")]
|
[assembly: AssemblyDescription("WPF Map Control Sample Surface Application")]
|
||||||
[assembly: AssemblyConfiguration("")]
|
[assembly: AssemblyConfiguration("")]
|
||||||
[assembly: AssemblyCompany("Clemens Fischer")]
|
[assembly: AssemblyCompany("Clemens Fischer")]
|
||||||
[assembly: AssemblyProduct("WPF Map Control")]
|
[assembly: AssemblyProduct("WPF Map Control")]
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue