Frage

Ich habe Probleme mit dem Gedächtnis zu erhöhen. Ich benutze MEF in caliburn.micro auf Schaffung neuer Bildschirm -. WPF-Fenster

Ansicht Modell der Bildschirm / Blick sieht wie folgt aus:

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

Bei der Erstellung I ExportFactory verwenden, Controler ist hier:

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();
    }
}

verwende ich ViewModelsControler Klasse in ChatScreenManager Klasse. Diese Klasse öffnen / entfernen Chat-Bildschirm.

Hier ist es:

  [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());
        }
    }

Und mein Problem ist:

  • nenne ich OpneChatScreen Methode von ChatScreenManager öffnen neue WPF-Fenster
  • In Bezug auf dieses Fenster in das Wörterbuch.
  • Wenn ich Fenster bin ich schließen RemoveChatScreen nennen.

In RemoveChaScreen:

  • Ich bekomme Gesamtspeicher, zum Beispiel ist es 37.000
  • Dann rufe ich dipose Methode auf ExportLifetimeContext chatScreen
  • Kraft GC
  • Und Gesamtspeicher erhalten, zum Beispiel ist es 39,000K

Der Speicherverbrauch ist stil zu erhöhen. Ich hoffe, wenn ich Dispose-Methode auf Objekt ChatViewModel nennen und auch ChatView Objekt dieses Objekt zerstört werden.

War es hilfreich?

Lösung

Zwingen GC nicht! Auch sollte die Dispose() Methode der Entnahme aus Ihrer Sammlung folgen.

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());
}

Erzwingen Garbage Collection wird nicht empfohlen. Es gibt Möglichkeiten zur Arbeit mit GC, aber, und das typischerweise in der Dispose () -Methode der Einweg-Klasse durchgeführt wird. Ihr abgeleitet ChatView Objekt sollte so etwas wie definiert werden:

class ChatView : IChatViewModel, IDisposable
{  }

ChatView erfordert eine Methode Dispose () implementiert werden. Es gibt ein Muster (von MSDN) , wenn Einweg-Klassen erstellen:

// 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);
    }
}
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top