6

MyClassタイプが1つある場合は、

[Export(typeof(Myclass))] 属性、および

[PartCreationPolicy(CreationPolicy.Shared)]

また

[PartCreationPolicy(CreationPolicy.NonShared)]

後で電話をかけようとしています

compositionContainer.GetExportedValue<Myclass>()複数回。

質問:最初の呼び出しで、MEFを介して登録済みクラスを取得します-すべての登録済みアセンブリをllokupしてから、1つの登録済み契約を見つけようとします。質問は2回目などです。MEFはグローバルルックアップを再度実行しますか、それとも内部のどこかにキャッシュしますか?

4

3 に答える 3

7

MEF は再度グローバル ルックアップを実行するか、内部のどこかにキャッシュしますか

はい、MEF のパフォーマンスについて質問がある場合、MEF はいくつかのキャッシュを実行し、遅延初期化を広く使用します。

1) メタデータ (構成可能パーツ、エクスポート定義、およびインポート定義) がキャッシュされます。例:

public override IEnumerable<ExportDefinition> ExportDefinitions
{
    get
    {
        if (this._exports == null)
        {
            ExportDefinition[] exports = this._creationInfo.GetExports().ToArray<ExportDefinition>();
            lock (this._lock)
            {
                if (this._exports == null)
                {
                    this._exports = exports;
                }
            }
        }
        return this._exports;
    }
}

2) エクスポートされたもキャッシュされます:

public object Value
{
    get
    {
        if (this._exportedValue == Export._EmptyValue)
        {
            object exportedValueCore = this.GetExportedValueCore();
            Interlocked.CompareExchange(ref this._exportedValue, exportedValueCore, Export._EmptyValue);
        }
        return this._exportedValue;
    }
}

もちろん、 を使用するCreationPolicy.NonSharedと、エクスポートされた値は要求時に何度も作成されます。ただし、この場合でも、メタデータはキャッシュされるため、「グローバル ルックアップ」は実行されません。

于 2013-01-11T09:36:31.253 に答える
0

値/メタデータは部分的にキャッシュされる可能性がありますが、いくつかのパフォーマンス テストを実行すると、呼び出しが行われるたびに何らかのルックアップが実行されることが示さGetExportedValueれます。したがって、値を取得する必要がある呼び出しが多数ある場合は、キャッシュを自分で行う必要があります。

namespace MEFCachingTest
{
    using System;
    using System.ComponentModel.Composition;
    using System.ComponentModel.Composition.Hosting;
    using System.ComponentModel.Composition.Primitives;
    using System.Diagnostics;
    using System.Reflection;

    public static class Program
    {
        public static CompositionContainer Container { get; set; }
        public static ComposablePartCatalog Catalog { get; set; }

        public static ExportedClass NonCachedClass
        {
            get
            {
                return Container.GetExportedValue<ExportedClass>();
            }
        }

        private static ExportedClass cachedClass;
        public static ExportedClass CachedClass
        {
            get
            {
                return cachedClass ?? (cachedClass = Container.GetExportedValue<ExportedClass>());
            }
        }

        public static void Main()
        {
            Catalog = new AssemblyCatalog(Assembly.GetExecutingAssembly());
            Container = new CompositionContainer(Catalog);

            const int Runs = 1000000;
            var stopwatch = new Stopwatch();

            // Non-Cached.
            stopwatch.Start();
            for (int i = 0; i < Runs; i++)
            {
                var ncc = NonCachedClass;
            }

            stopwatch.Stop();
            Console.WriteLine("Non-Cached: Time: {0}", stopwatch.Elapsed);

            // Cached.
            stopwatch.Restart();
            for (int i = 0; i < Runs; i++)
            {
                var cc = CachedClass;
            }

            stopwatch.Stop();
            Console.WriteLine("    Cached: Time: {0}", stopwatch.Elapsed);
        }
    }

    [Export]
    [PartCreationPolicy(CreationPolicy.Shared)]
    public class ExportedClass
    {
    }
}

その他のバリエーションについては、この要旨をご覧ください: https://gist.github.com/DanielRose/d79f0da2ef61591176ce

私のコンピューターでは、Windows 7 x64、.NET 4.5.2:

Non-Cached: Time: 00:00:02.1217811
    Cached: Time: 00:00:00.0063479

NuGet から MEF 2 を使用する:

Non-Cached: Time: 00:00:00.2037812
    Cached: Time: 00:00:00.0023358

私が働いている実際のアプリケーションでは、これによりアプリケーションが 6 倍遅くなりました。

于 2014-12-12T14:21:03.307 に答える
0

を使用すると、毎回検索が行われます[PartCreationPolicy(CreationPolicy.NonShared)]。次に、キャッシュを自分で実装する必要があります。

デフォルトの実装では、Singleton パターンを使用しています。これは属性と同じです[PartCreationPolicy(CreationPolicy.Shared)]これがベスト プラクティスです。

詳細については、http://blogs.microsoft.co.il/blogs/bnaya/archive/2010/01/09/mef-for-beginner-part-creation-policy-part-6.aspxを参照してください。

于 2013-01-11T08:48:09.527 に答える