質問

メモリの増設に問題があります。新しい画面の作成 - WPFウィンドウでcaliburn.microのMEFを使用します。

画面/ビューのビュー モデルは次のようになります。

[Export(typeof(IChatViewModel))]
[PartCreationPolicy(CreationPolicy.NonShared)]
public class ChatViewModel : Screen, IChatViewModel
    {}

作成時に ExportFactory を使用します。コントローラーは次のとおりです。

public interface IViewModelsControler
{
    ExportLifetimeContext<IChatViewModel> CreatChatViewModel();
}

[Export(typeof(IViewModelsControler))]
public class ViewModelsControler : IViewModelsControler
{
    [Import]
    public ExportFactory<IChatViewModel> ChatViewFactory { get; set; }

    public ExportLifetimeContext<IChatViewModel> CreatChatViewModel()
    {
        return ChatViewFactory.CreateExport();
    }
}

ChatScreenManagerクラスのViewModelsControlerクラスを使用します。このクラスはチャット画面を開く/削除します。

はい、これ:

  [Export(typeof(IChatScreenManager))]
    public class ChatScreenManager : IChatScreenManager
    {
        private IWindowManager _windowManager;

        [Import]
        public IViewModelsControler ViewModelControler { get; set; }

        [ImportingConstructor]
        public ChatScreenManager(IWindowManager windowManager)
        {
            _windowManager = windowManager;
            ActiveChatScreens = new Dictionary<string, ExportLifetimeContext<IChatViewModel>>();
        }

        //store active screen
        public Dictionary<string, ExportLifetimeContext<IChatViewModel>> ActiveChatScreens { get; set; }


        public void OpenChatScreen(DetailData oponent, string avatarNick, BitmapImage avatarImage)
        {
            if (!ActiveChatScreens.ContainsKey(oponent.Info.Nick))
            {
                //create new chat screen with view model controler
                ExportLifetimeContext<IChatViewModel> chatScreen = ViewModelControler.CreatChatViewModel();

                //show
                _windowManager.Show(chatScreen.Value);

                //add ref to the dic
                ActiveChatScreens.Add(oponent.Info.Nick, chatScreen);
            }
        }

        public void RemoveChatScreen(string clossingScreen)
        {

            MessageBox.Show(GC.GetTotalMemory(true).ToString());

            ActiveChatScreens[clossingScreen].Dispose();

            ActiveChatScreens.Remove(clossingScreen);

            GC.Collect();
            GC.SuppressFinalize(this);

            MessageBox.Show(GC.GetTotalMemory(true).ToString());
        }
    }

そして私の問題は次のとおりです。

  • ChatScreenManager から OpneChatScreen メソッドを呼び出して、新しい WPF ウィンドウを開きます
  • このウィンドウの参照を辞書に追加します。
  • ウィンドウを閉じるときに、RemoveChatScreen を呼び出します。

RemoveChaScreen で:

  • 合計メモリを取得します。たとえば、37,000K です。
  • 次に、ExportLifetimeContext chatScreen で Dipose メソッドを呼び出します
  • 強制GC
  • そして、合計メモリを取得します。たとえば、39,000K です。

メモリ使用量は依然として増加しています。ChatViewModel オブジェクトと ChatView オブジェクトの Dispose メソッドを呼び出すと、これらのオブジェクトが破棄されることを願っています。

役に立ちましたか?

解決

GCを強制しないでください!また、Dispose()方法は、あなたのコレクションからの除去に従わなければならない。

public void RemoveChatScreen(string closingScreen)
{
    MessageBox.Show(GC.GetTotalMemory(true).ToString());

    IChatViewModel chatWindow = ActiveChatScreens[closingScreen]

    // remove from collection - GC may pass over object referenced in collection
    // until next pass, or 3rd pass...who knows, it's indeterminate
    ActiveChatScreens.Remove(closingScreen);

    // all clean up should be performed within Dispose method
    chatWindow.Dispose(); 

    //GC.Collect();
    //GC.SuppressFinalize(this);

    MessageBox.Show(GC.GetTotalMemory(true).ToString());
}

ガベージコレクションを強制することはお勧めしません。そこの仕事のやり方は、しかし、GCであり、そしてそれは、一般的に使い捨てクラスの処分()メソッドで行われます。あなたの派生ChatViewオブジェクトのようなものを定義する必要があります:

class ChatView : IChatViewModel, IDisposable
{  }

ChatViewは廃棄()メソッドを実装することを必要とします。 の<フォローするパターンがありますem>の使い捨てのクラスを作成するときにの(MSDNから):

// Design pattern for a base class.
public class ChatView : IChatViewModel, IDisposable
{
    private bool disposed = false;

    //Implement IDisposable.
    public void Dispose()
    {
        Dispose(true);
        GC.SuppressFinalize(this);
    }

    protected virtual void Dispose(bool disposing)
    {
        if (!disposed)
        {
            if (disposing)
            {
                // Free other state (managed objects).
            }
            // Free your own state (unmanaged objects).
            // Set large fields to null.
            disposed = true;
        }
    }

    // Use C# destructor syntax for finalization code.
    ~ChatView()
    {
        // Simply call Dispose(false).
        Dispose (false);
    }
}
scroll top