3

空でないコンストラクターを持つシングルトンを作成し、同期した方法でアクセスしようとしています。コンポーネントの初期化の順序を制御できないため、コンポーネントが初期化される前にシングルトンにアクセスする場合は、次のようにする必要があります。待つ。

ファクトリメソッドが1回だけ呼び出され、初期化フェーズで例外がスローされます

private static volatile GottwareExcelAddin _instance;   
private static readonly ManualResetEvent InitializedEvent=new ManualResetEvent(false);

    internal static Singleton CurrentInstance
    {
        get
        {
            InitializedEvent.WaitOne();
            return _instance;
        }
    }

    #endregion

    private Singleton(String url, Int otherstuff)
    {
       // do stuff
        InitializedEvent.Set();
    }


    #region public factory
    [OnWorkerThread]
    public static void Singleton(String spaceUrl, _Application excelApp)
    {
        if (_instance == null)
            _instance = new Singleton(spaceUrl, excelApp);
    }

[OnWorkerThread]は、ファクトリをワーカースレッドで実行するための属性であり、ファクトリは1回だけ呼び出されます。

myappを起動すると、次のようになることがあります。

例外ソース:mscorlib例外タイプ:System.Runtime.InteropServices.SEHException例外メッセージ:外部コンポーネントが例外をスローしました。例外ターゲットサイト:WaitOneNative

----スタックトレース----System.Threading.WaitHandle.WaitOneNative(waitableSafeHandle As SafeHandle、msilesTimeout As UInt32、hasThreadAffinity As Boolean、exitContext As Boolean)AddinExpress.RTD.2005.dll:N 00000(0x0)JITシステム。 Threading.WaitHandle.InternalWaitOne(waitableSafeHandle As SafeHandle、msilsTimeout As Int64、hasThreadAffinity As Boolean、exitContext As Boolean)AddinExpress.RTD.2005.dll:N 0020(0x14)IL System.Threading.WaitHandle.WaitOne(millisecondsTimeout As Int32、exitContextブール値)

私は何が間違っていますか?

4

1 に答える 1

6

そこに適切なシングルトンを作成していません。適切なシングルトンには、それにアクセスするための静的メソッドとプライベートコンストラクターが必要です。

もう1つの問題は、シングルトンを初期化するパラメーターがある場合、異なるパラメーターを使用してシングルトンを複数回初期化するとはどういう意味ですか?エラーですか?

異なるパラメーターを使用した複数の初期化を無視できると仮定すると、次のように実装できます(ただし、どこかで設計エラーが発生する可能性があります)。

class Singleton
{
    public static Singleton Instance(string param1, int param2)
    {
        if (_instance == null)
        {
            lock (_locker)
            {
                if (_instance == null) // Double-checked locking (works in C#!).
                {
                    _instance = new Singleton(param1, param2);
                }
            }
        }

        return _instance;
    }

    private Singleton(string param1, int param2)
    {
        // Whatever.
    }

    private static Singleton _instance;
    private static readonly object _locker = new object();
}

私は通常Lazyを使用してシングルトンを実装しますが、シングルトンのコンストラクターがシングルトンのアクセスポイントで渡されるパラメーターを必要とする場合はあまり役に立ちません。

于 2012-04-04T08:43:34.167 に答える