1

私が現在抱えている問題と解決策について説明しましょう。おそらく、それが悪い考えである理由(そうだと仮定して)と、それをより良いシステムにするために私ができることについて教えてください。

現在、ファイルを解析してcsvまたは他の形式にリッピングする600個の「リッパー」があります。リッパーはすべて、共通のインターフェースと基本クラスを実装しています。ジョブの構成に応じてジョブがキューに入れられる時点で、リフレクションを使用して特定のリッパーが呼び出されます。

            foreach (var stream in streams)
            {
                try
                {
                    // load it
                    Assembly asm = Assembly.LoadFile(Path.Combine(stream.RipperPath, stream.RipperFileName), new Evidence());
                    if (asm == null)
                    {
                        MessageBox.Show(String.Format("Invalid Interface ripper loaded.\n{0}", Path.Combine(stream.RipperPath, stream.RipperFileName)));
                        return;
                    }

                    foreach (Type objType in asm.GetTypes())
                    {
                        if (!objType.IsPublic)
                            continue;

                        // make sure the type isn't Abstract
                        if (((objType.Attributes & TypeAttributes.Abstract) == TypeAttributes.Abstract))
                            continue;

                        // IRipper is the interface that all of the Rippers must implement to be loaded
                        Type objInterface = objType.GetInterface("IRipper", true);
                        if (objInterface == null)
                            continue;

                        try
                        {
                            var iri = (IRipper)Activator.CreateInstance(objType);

                            // Rippers must register with their hosts
                            iri.Host = this;
                            iri.OnStart += RipperStart;
                            iri.OnComplete += RipperComplete;
                            iri.OnProgressChanged += RipperStatusUpdate;
                            iri.dataStream = stream;
                        }
                        catch (Exception ex)
                        {
                            Console.WriteLine(ex.Message);
                        }
                    }
                }
                catch (Exception ex)
                {
                    MessageBox.Show(String.Format("Error loading interface: {0}\n{1}", Path.Combine(stream.RipperPath, stream.RipperFileName), ex.Message));
                }
            } 

すべてのリッパーには、インターフェースがそれらを縮小する「Rip()」と呼ばれる関数が実装されています。

現在のコードを使用すると、600個のアセンブリをロードした後(必要なときにロードされるため)、使用後にアンロードしないと少し遅くなり始めるという問題があります。

あなたは何を提案しますか?

4

2 に答える 2

1

実際に 600 の異なるリッパー、または 600 のストリームと少数のリッパーがありますか? 各リッパーを独自のアセンブリにする必要がありますか? リッパーをひとまとめにすることができれば、アセンブリの数を大幅に減らすことができます。ストリームの詳細に型名と実行可能ファイルが含まれている場合、複数のリッパーを使用でき、それらのアセンブリを調べる必要はありません。呼び出すだけAssembly.GetTypeです。

アセンブリごとに実際にどれだけのオーバーヘッドがあるかはわかりません.600個のアセンブリがかなりの量のメモリを占有すると予想されますが、それ以上のパフォーマンスにはあまり影響しません.

Managed Extensibility Framework (MEF)も検討する必要があるかもしれませんが、全体的なアプローチは合理的です。私がするもう1つのことは、「ストリームの処理」コードから「リッパーの取得」を除外することです:)

于 2009-03-16T17:19:29.683 に答える
0

System.Addinの内容を確認することをお勧めします。アドインは独自のアプリ ドメインに読み込まれているようです。これにより、アドインが不要になったときにクリーンにアンロードできます。

于 2009-03-16T17:26:50.477 に答える