2011-01-05 2 views
0

메모리 증가 문제가 있습니다. 필자는 caliburn.micro에서 MEF를 사용하여 새 화면 - WPF 창을 만듭니다. 화면/뷰의Caliburn.Micro에서 MEF로 내보내기 - 메모리 문제 증가

보기 모델은 다음과 같이 : 나는 ExportFactory을 사용하여 생성에

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

는 CONTROLER은 여기에 있습니다 :

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

그리고 내 문제는 다음과 같습니다 : 여기

그것을이다

  • 내가 그것을 사전에이 창에 대한 참조를 추가합니다 새 WPF 창
  • 을 열 ChatScreenManager에서 OpneChatScreen 메서드를 호출합니다.
  • 창을 닫을 때 RemoveChatScreen을 호출합니다.
  • RemoveChaScreen에서

는 :

  • 내가 총 메모리 얻을, 예를 들어,이 37,000K
  • 가 그럼 난 ExportLifetimeContext chatScreen에 Dipose 메소드를 호출
  • 강제 GC
  • 그리고 총 메모리를 얻을 수있다 예를 들면 39,000K

메모리 사용량은 ing. 개체 ChatViewModel 및 ChatView 개체를 Dispose 메서드를 호출하면 이러한 개체가 파괴되기를 바랍니다.

+0

, 코드 샘플이 제대로 포맷 할 수 있도록 질문을 식별 할 [C#을] 또는 [인터넷] 태그를 사용합니다. ;) – IAbstract

답변

2

강제로 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로 작업 할 수있는 방법이 있으며 일회용 클래스의 Dispose() 메소드에서 일반적으로 수행됩니다. 파생 된 ChatView 객체는 다음과 같이 정의해야합니다.

class ChatView : IChatViewModel, IDisposable 
{ } 

ChatView를 사용하려면 Dispose() 메소드를 구현해야합니다. 일회용 클래스를 만들 때 (MSDN에서)를 pattern to follow있습니다 :

참고
// 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); 
    } 
} 
+0

조언을 주셔서 감사합니다. 내 문제는 어떻게 WPF 창 (보기는 WPF 창)에서 "View Dispose Method"를 사용하여 ViewModel 클래스의 메소드를 Dispose에 연결하는 방법입니다. 예를 들어 ViewModel 클래스의 Dispose 메서드를 호출하고 View-WPF 윈도우 개체의 Dipose 메서드를 호출합니다. –

+0

예를 들어 ViewModel에서 Dispose Method를 호출하고 WPF Window 인 destroy View를 호출합니다. –

+0

나는 http://stackoverflow.com/questions/4597317/problem-with-mef-exportfactoryt-call-dispose-method/4599836#4599836가 대답했다고 생각합니다. – IAbstract