0

についてかなり理論的な質問があり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();
    }
}
4

0 に答える 0