についてかなり理論的な質問がありThreadLocal<T>
ます。接続の切断など、周囲の世界で時折発生するイベントにより、T が使用できなくなる可能性があります。オブジェクト全体をリセットせずに、オブジェクトが使用できなくなったスレッドに関連して ThreadLocal 値をリセットする方法についてのアイデアはありThreadLocal<T>
ますか?
ところで
私のコンテキストはASP.NET MVCです。私は似たようなこと
ThreadLocal<DatabaseConnection>
をしています(私の場合、それを行うのには十分な理由があります)したがって、ユーザーが「Bang! あなたのプログラムに障害が発生しました。このプログラムを作成した開発者は脳死のゾンビです」などの例外を表示するソリューションはオプションではありません...
このパズルを楽しんで、よろしくお願いします。
編集: 1分あたり512のクライアントリクエストを処理する8つのスレッドのプールを持つWebサーバーを想像してください。上記のソリューションを使用して、同じ期間内に512の接続を作成するのではなく、開いている接続の量を1分あたり8接続に制限しています時間の...
編集:これが私の問題に関連するソースです。「特定のスレッドでデータベースへの接続が失われた場合はどうなるか」という質問を自問しています。ThreadLocal 内で再作成して再設定するにはどうすればよいですか?
パブリック クラス EloqueraThreadLocalInstanceFactory
public class EloqueraThreadLocalInstanceFactory
{
Property<DB> database;
private DB CreateInstance()
{
var db = new DB(ConnectionString);
try
{
db.OpenDatabase(DatabaseName);
}
catch (FileNotFoundException)
{
db.CreateDatabase(DatabaseName);
db.OpenDatabase(DatabaseName);
}
return db;
}
public EloqueraThreadLocalInstanceFactory(String connectionString, String databaseName, params Action<DB>[] initializers)
{
DatabaseName = databaseName;
ConnectionString = connectionString;
database = new ThreadLocalPropertyValue<DB>(CreateInstance, initializers);
}
public String DatabaseName { get; private set; }
public String ConnectionString { get; private set; }
public DB GetInstance()
{
return database;
}
}
パブリック クラス プロパティ { ... }
public class Property<T>
{
private PropertyValue<T> propertyValue;
protected virtual void OnAfterSet()
{
if (AfterSet != null)
{
AfterSet(this, null);
}
}
protected virtual void OnBeforeGet(EventArgs<T> eventArgs)
{
if (BeforeGet != null)
{
BeforeGet(this, eventArgs);
}
}
protected virtual void OnBeforeSet(CancellableEventArgs<PropertyValue<T>> e)
{
if (BeforeSet != null)
{
BeforeSet(this, e);
}
}
public Property()
{
}
public Property(PropertyValue<T> propertyValue)
{
this.propertyValue = propertyValue;
}
public void Reset()
{
propertyValue = null;
}
// IsSet is required to be implemented via method to prevent it from being serialized
public Boolean IsSet()
{
return propertyValue != null;
}
// Value property is required for serialization purposes
public T Value
{
get { return Get(); }
set { Set(new StaticPropertyValue<T>(value)); }
}
protected void SetRaw(PropertyValue<T> propertyValue)
{
this.propertyValue = propertyValue;
}
protected virtual T Get()
{
var eventArgs = new EventArgs<T>(propertyValue.GetPropertyValueInternal());
OnBeforeGet(eventArgs);
return eventArgs.Value;
}
protected virtual void Set(PropertyValue<T> propertyValue)
{
var eventArgs = new CancellableEventArgs<PropertyValue<T>>(propertyValue);
OnBeforeSet(eventArgs);
this.propertyValue = propertyValue;
if (!eventArgs.Cancel)
{
SetRaw(propertyValue);
OnAfterSet();
}
}
public event EventHandler AfterSet;
public event EventHandler<EventArgs<T>> BeforeGet;
public event EventHandler<CancellableEventArgs<PropertyValue<T>>> BeforeSet;
public static implicit operator T(Property<T> property)
{
return property == null ? default(T) : property.Get();
}
public static implicit operator Property<T>(T value)
{
return new Property<T>(new StaticPropertyValue<T>(value));
}
public static implicit operator Property<T>(Func<T> value)
{
return new Property<T>(new LazyPropertyValue<T>(value));
}
public static implicit operator Property<T>(PropertyValue<T> value)
{
return new Property<T>(value);
}
public static implicit operator PropertyValue<T>(Property<T> property)
{
return property.propertyValue;
}
/***************************************************************************************************/
public static Property<T> operator <=(Property<T> property, Func<T> propertyValue)
{
if (property != null)
{
property.Set(new LazyPropertyValue<T>(propertyValue));
}
else
{
return new Property<T>(new LazyPropertyValue<T>(propertyValue));
}
return property;
}
public static Property<T> operator >=(Property<T> property, Func<T> propertyValue)
{
property.Set(new LazyPropertyValue<T>(propertyValue));
return property;
}
public static Property<T> operator <=(Property<T> property, PropertyValue<T> propertyValue)
{
if (property != null)
{
property.Set(propertyValue);
}
else
{
return new Property<T>(propertyValue);
}
return property;
}
public static Property<T> operator >=(Property<T> property, PropertyValue<T> propertyValue)
{
property.Set(propertyValue);
return property;
}
public static Property<T> operator <=(Property<T> property, LazyPropertyValue<T> propertyValue)
{
if (property != null)
{
property.Set(propertyValue);
}
else
{
return new Property<T>(propertyValue);
}
return property;
}
public static Property<T> operator >=(Property<T> property, LazyPropertyValue<T> propertyValue)
{
property.Set(propertyValue);
return property;
}
public static Property<T> operator <=(Property<T> property, StaticPropertyValue<T> propertyValue)
{
if (property != null)
{
property.Set(propertyValue);
}
else
{
return new Property<T>(propertyValue);
}
return property;
}
public static Property<T> operator >=(Property<T> property, StaticPropertyValue<T> propertyValue)
{
property.Set(propertyValue);
return property;
}
/***************************************************************************************************/
public static Property<T> operator <(Property<T> property, Func<T> propertyValue)
{
if (property != null)
{
property.SetRaw(new LazyPropertyValue<T>(propertyValue));
}
else
{
return new Property<T>(new LazyPropertyValue<T>(propertyValue));
}
return property;
}
public static Property<T> operator >(Property<T> property, Func<T> propertyValue)
{
property.SetRaw(new LazyPropertyValue<T>(propertyValue));
return property;
}
public static Property<T> operator <(Property<T> property, PropertyValue<T> propertyValue)
{
if (property != null)
{
property.SetRaw(propertyValue);
}
else
{
return new Property<T>(propertyValue);
}
return property;
}
public static Property<T> operator >(Property<T> property, PropertyValue<T> propertyValue)
{
property.SetRaw(propertyValue);
return property;
}
public static Property<T> operator <(Property<T> property, LazyPropertyValue<T> propertyValue)
{
if (property != null)
{
property.SetRaw(propertyValue);
}
else
{
return new Property<T>(propertyValue);
}
return property;
}
public static Property<T> operator >(Property<T> property, LazyPropertyValue<T> propertyValue)
{
property.SetRaw(propertyValue);
return property;
}
public static Property<T> operator <(Property<T> property, StaticPropertyValue<T> propertyValue)
{
if (property != null)
{
property.SetRaw(propertyValue);
}
else
{
return new Property<T>(propertyValue);
}
return property;
}
public static Property<T> operator >(Property<T> property, StaticPropertyValue<T> propertyValue)
{
property.SetRaw(propertyValue);
return property;
}
}
public abstract class PropertyValue<T>
{
protected abstract T GetPropertyValue();
internal T GetPropertyValueInternal()
{
return GetPropertyValue();
}
}
public class InitializablePropertyValue<T> : PropertyValue<T>
{
private Func<T> func;
private Action<T>[] initializers;
public InitializablePropertyValue(Func<T> func, params Action<T>[] initializers)
{
if (func == null) throw new ArgumentNullException("func");
if (initializers == null) throw new ArgumentNullException("initializers");
this.func = func;
this.initializers = initializers;
}
protected override T GetPropertyValue()
{
var result = func();
foreach (var initializer in initializers)
{
initializer(result);
}
return result;
}
}
public class StaticPropertyValue<T> : PropertyValue<T>
{
private T value;
public StaticPropertyValue(T value)
{
this.value = value;
}
protected override T GetPropertyValue()
{
return value;
}
public static implicit operator StaticPropertyValue<T>(T value)
{
return new StaticPropertyValue<T>(value);
}
}
public class LazyPropertyValue<T> : InitializablePropertyValue<T>
{
private Lazy<T> lazy;
public LazyPropertyValue(Func<T> valueFactory)
: base(valueFactory)
{
this.lazy = new Lazy<T>(base.GetPropertyValue, false);
}
public LazyPropertyValue(Func<T> valueFactory, Boolean isThreadSafe)
: base(valueFactory)
{
this.lazy = new Lazy<T>(base.GetPropertyValue, isThreadSafe);
}
public LazyPropertyValue(Func<T> valueFactory, LazyThreadSafetyMode mode)
: base(valueFactory)
{
this.lazy = new Lazy<T>(base.GetPropertyValue, mode);
}
public LazyPropertyValue(Func<T> valueFactory, params Action<T>[] initializers)
: base(valueFactory, initializers)
{
this.lazy = new Lazy<T>(base.GetPropertyValue, false);
}
public LazyPropertyValue(Func<T> valueFactory, Boolean isThreadSafe, params Action<T>[] initializers)
: base(valueFactory, initializers)
{
this.lazy = new Lazy<T>(base.GetPropertyValue, isThreadSafe);
}
public LazyPropertyValue(Func<T> valueFactory, LazyThreadSafetyMode mode, params Action<T>[] initializers)
: base(valueFactory, initializers)
{
this.lazy = new Lazy<T>(base.GetPropertyValue, mode);
}
public Boolean IsInitialized
{
get { return lazy.IsValueCreated; }
}
protected override T GetPropertyValue()
{
return lazy.Value;
}
public static implicit operator LazyPropertyValue<T>(Func<T> value)
{
return new LazyPropertyValue<T>(value);
}
}
public class ThreadLocalPropertyValue<T> : InitializablePropertyValue<T>
{
ThreadLocal<T> threadLocal;
public ThreadLocalPropertyValue(Func<T> func, params Action<T>[] initializers)
: base(func, initializers)
{
this.threadLocal = new ThreadLocal<T>(base.GetPropertyValue);
}
protected override T GetPropertyValue()
{
return threadLocal.Value;
}
}
public class DynamicPropertyValue<T> : PropertyValue<T>
{
Func<T> func;
public DynamicPropertyValue(Func<T> func)
{
this.func = func;
}
protected override T GetPropertyValue()
{
return func();
}
}