5

C# .NET 4.0 Windows サービス アプリケーションで ILMerge と Quartz.NET を使用しています。アプリは ILMerge を使用しなくても正常に動作しますが、出荷リリースが近づいているため、すべての DLL を 1 つの実行可能ファイルに結合したいと考えました。

問題は、ILMerge が正常に動作しているように見えることですが、結合された実行可能ファイルを実行すると、次の例外がスローされます。

未処理の例外: Quartz.SchedulerException: ThreadPool タイプ 'Quartz.Simpl.SimpleThreadPool' をインスタンス化できませんでした。---> System.InvalidCastException: タイプ「Quartz.Simpl.SimpleThreadPool」のオブジェクトをタイプ「Quartz.Spi.IThreadPool」にキャストできません。
at Quartz.Util.ObjectUtils.InstantiateType[T](Type type) in :line 0
at Quartz.Impl.StdSchedulerFactory.Instantiate() in :line 0
--- 内部例外スタック トレースの終わり ---
at Quartz.Impl. StdSchedulerFactory.Instantiate() : 行 0
で Quartz.Impl.StdSchedulerFactory.GetScheduler() : 行 0

これがなぜなのか誰にも分かりますか?私はすでに 4 時間以上無駄にしていますが、それを理解することはできません。ILMerge と組み合わせない場合、すべて正常に動作します (Quartz.dll と Common.Logging.dll は同じディレクトリにあります)。

誰かが Quartz.net をこのようにパッケージ化しようとしたに違いないと確信しています。何かアイデアはありますか?

4

2 に答える 2

1

独自の ISchedulerFactory を作成し、リフレクションを使用してすべての型をロードすることを避けることができます。StdSchedulerFactory は、このコードを使用してスレッドプールを作成します。エラーが発生している場所であり、変更を検討し始める場所です。

        Type tpType = loadHelper.LoadType(cfg.GetStringProperty(PropertyThreadPoolType)) ?? typeof(SimpleThreadPool);

        try
        {
            tp = ObjectUtils.InstantiateType<IThreadPool>(tpType);
        }
        catch (Exception e)
        {
            initException = new SchedulerException("ThreadPool type '{0}' could not be instantiated.".FormatInvariant(tpType), e);
            throw initException;
        }

呼び出される ObjectUtils.InstantiateType メソッドはこれで、最後の行は例外をスローする行です。

    public static T InstantiateType<T>(Type type)
    {
        if (type == null)
        {
            throw new ArgumentNullException("type", "Cannot instantiate null");
        }
        ConstructorInfo ci = type.GetConstructor(Type.EmptyTypes);
        if (ci == null)
        {
            throw new ArgumentException("Cannot instantiate type which has no empty constructor", type.Name);
        }
        return (T) ci.Invoke(new object[0]);
    }

ファクトリのこのセクションの直後に、同じパターンを使用してデータソースがロードされ、ジョブ自体も動的にロードされます。つまり、独自の JobFactory も作成する必要があります。Quartz.Net は実行時に一連のビットとピースを動的にロードするため、この道を進むと、かなりの量のものを書き直すことになる可能性があります。

于 2013-05-05T19:30:20.443 に答える