سؤال

لدي مشكلة في زيادة الذاكرة. يمكنني استخدام MEF في Caliburn.micro على إنشاء شاشة جديدة - WPF.

عرض نموذج الشاشة/العرض يبدو هكذا:

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

يمكنني استخدام فئة 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());
        }
    }

ومشكلتي هي:

  • أدعو Opnechatscreen طريقة من الدردشة
  • أضف مرجعًا على هذه النافذة إلى القاموس.
  • عندما أغلق نافذة أسميها removechatscreen.

في removechascreen:

  • أحصل على إجمالي الذاكرة ، على سبيل المثال ، هو 37000 ألف
  • ثم أسمي طريقة dipose على orportlifetimecontext chatscreen
  • قوة GC
  • واحصل على إجمالي الذاكرة ، على سبيل المثال هو 39000K

استخدام الذاكرة يتزايد. آمل أن أتصل بـ Dispose Method على الكائن chatviewmodel وأيضًا كائن 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 () للفئة التي يمكن التخلص منها. يجب تعريف كائن 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);
    }
}
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top