Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/sql-server-2008/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 在Caliburn中使用MEF导出。微增加内存问题_C#_Ioc Container_Mef_Caliburn.micro - Fatal编程技术网

C# 在Caliburn中使用MEF导出。微增加内存问题

C# 在Caliburn中使用MEF导出。微增加内存问题,c#,ioc-container,mef,caliburn.micro,C#,Ioc Container,Mef,Caliburn.micro,我有增加记忆力的问题。我在caliburn.micro中使用MEF创建新屏幕-WPF窗口 屏幕/视图的视图模型如下所示: [Export(typeof(IChatViewModel))] [PartCreationPolicy(CreationPolicy.NonShared)] public class ChatViewModel : Screen, IChatViewModel {} 在我使用ExportFactory创建时,Controller位于: public interfa

我有增加记忆力的问题。我在caliburn.micro中使用MEF创建新屏幕-WPF窗口

屏幕/视图的视图模型如下所示:

[Export(typeof(IChatViewModel))]
[PartCreationPolicy(CreationPolicy.NonShared)]
public class ChatViewModel : Screen, IChatViewModel
    {}
在我使用ExportFactory创建时,Controller位于:

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();
    }
}
公共接口IViewModelController
{
ExportLifetimeContext CreatChatViewModel();
}
[导出(类型(IViewModelController))]
公共类ViewModelsController:IViewModelsController
{
[进口]
公共ExportFactory ChatViewFactory{get;set;}
公共ExportLifetimeContext CreatChatViewModel()
{
返回ChatViewFactory.CreateExport();
}
}
我在ChatScreenManager类中使用ViewModelsController类。此类打开/删除聊天屏幕

这是:

  [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());
        }
    }
[导出(类型化(IChatScreenManager))]
公共类ChatScreenManager:IChatScreenManager
{
专用iWindows管理器\u windowManager;
[进口]
公共IViewModelControllerViewModelControllerGet;set;}
[导入构造函数]
公共聊天室屏幕管理器(iWindows管理器windowManager)
{
_windowManager=windowManager;
ActiveChatScreens=新字典();
}
//存储活动屏幕
公共字典ActiveChatScreens{get;set;}
public void OpenChatScreen(DetailData opont、字符串avatarNick、位图图像avatarImage)
{
如果(!ActiveChatScreens.ContainsKey(opont.Info.Nick))
{
//使用视图模型控制器创建新的聊天屏幕
ExportLifetimeContext chatScreen=ViewModelController.CreatChatViewModel();
//展示
_windowManager.Show(chatScreen.Value);
//将ref添加到dic
添加(opont.Info.Nick,chatScreen);
}
}
public void RemoveChatScreen(字符串关闭屏幕)
{
Show(GC.GetTotalMemory(true.ToString());
ActiveChatScreens[clossingScreen].Dispose();
ActiveChatScreens.移除(clossingScreen);
GC.Collect();
总干事(本);
Show(GC.GetTotalMemory(true.ToString());
}
}
我的问题是:

  • 我从ChatScreenManager调用OpneChatScreen方法来打开新的WPF窗口
  • 将此窗口上的引用添加到词典中
  • 当我关闭窗口时,我调用RemoveChatScreen
在RemoveChasScreen中:

  • 我得到了总内存,比如37000K
  • 然后在ExportLifetimeContext聊天屏幕上调用Dipose方法
  • 强制GC
  • 并获取总内存,例如它是39000K吗

内存使用仍在增加。我希望如果我调用对象ChatViewModel上的Dispose方法,也调用ChatView对象,这些对象将被销毁。

不要强制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类的Dispose()方法中完成的。派生的ChatView对象应定义如下:

class ChatView : IChatViewModel, IDisposable
{  }
ChatView需要实现Dispose()方法。创建一次性类时,存在一个(来自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);
    }
}

仅供参考,请使用[c#]或[net]标记来识别您的问题,以便代码示例可以正确格式化感谢您的建议,我现在的问题是如何将ViewModel类中的Dispose方法与WPF窗口(视图是WPF窗口)上的“View Dispose method”连接起来。例如,我在ViewModel类上调用Dispose方法,它也在View-WPF窗口对象上调用Dipose方法。例如,我在ViewModel上调用Dispose方法,它也调用destroy视图,它是WPF窗口。我想我已经为您解答了。很抱歉,您不理解我。你了解MVVM吗,caliburn.micro?因此,您可以使用caliburn创建简单的MVVM WPF应用程序。为此视图创建视图(WPF窗口)和视图模型。使用MEF导出此视图模型类。并尝试从视图模型类中销毁视图对象。您可以在视图模型类上实现IDisposable接口,但这并不能解决此问题。因为您只在视图模型类上销毁类型为位图。@jminarik-不要忘记
Dispose
的作用,以便安全地处置非托管对象并将处置链接到其他托管对象。您可以随意调用
Dispose
,清理项目使用的资源和非托管资源,但您仍然需要等待GC进行清理。你也不应该强迫这样做。如果你真的很担心内存占用的话,我真的会看看你的应用程序到底是怎么引起你记忆问题的。