Форум программистов, компьютерный форум, киберфорум
C#: WPF, UWP и Silverlight
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск  
 
 
Рейтинг 4.89/18: Рейтинг темы: голосов - 18, средняя оценка - 4.89
 Аватар для limeniye
1182 / 624 / 160
Регистрация: 19.04.2018
Сообщений: 2,923

MVVM Утечка памяти

12.06.2022, 20:22. Показов 4411. Ответов 82
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Собственно сделал подписку: _messageService.MessagesChanged += OnMessagesChanged; в VM.
А отписывать-то как?

Сделал так:

https://github.com/LimeniyeCyb... del.cs#L82

Но даже не понимаю.что сделал. Этого будет достаточно?
0
Лучшие ответы (1)
Programming
Эксперт
39485 / 9562 / 3019
Регистрация: 12.04.2006
Сообщений: 41,671
Блог
12.06.2022, 20:22
Ответы с готовыми решениями:

Утечка памяти с картинками
у меня есть вот такой контрол <StackPanel x:Name="StackEmoji" Grid.Row="1" Grid.Column="1" ...

Dispatch timer - Утечка памяти
Всем привет. Пишу на подобные форумы первый раз. Хотел бы попросить помочь разобраться в ситуации с "утечкой памяти". Есть...

Утечка памяти в Awesomium WebControl
Всем привет. Использую в качестве встроенного браузера Awesomium, но вот проблема, уже страниц через 20 процесс awesomium_process.exe...

82
 Аватар для Andrey-MSK
3392 / 2278 / 388
Регистрация: 14.08.2018
Сообщений: 7,719
Записей в блоге: 4
15.07.2022, 11:46
Студворк — интернет-сервис помощи студентам
Цитата Сообщение от Andrey-MSK Посмотреть сообщение
Сейчас сижу переписываю сервис окон, чтобы можно было его научить передавать параметры в VM. Как придумаю, покажу
В общем нашел как сие провернуть Если кому интересно, то передаются параметры в VM из сервиса вот так:
Создаём сервис для получения VM, нечто типа такого
IViewModelFactory
C#
1
2
3
4
5
6
7
namespace Services.Interfaces
{
    public interface IViewModelFactory
    {
        T CreateViewModel<T>() where T : IBaseViewModel;
    }
}
ViewModelFactory
C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
using System;
 
using Microsoft.Extensions.DependencyInjection;
 
using Services.Interfaces;
 
namespace HRClient.Services
{
    internal class ViewModelFactory : IViewModelFactory
    {
        private readonly IServiceProvider _serviceProvider;
 
        public ViewModelFactory(IServiceProvider serviceProvider)
        {
            _serviceProvider = serviceProvider;
        }
 
        public T CreateViewModel<T>() where T : IBaseViewModel
            => _serviceProvider.GetService<T>();
    }
}
Создаём сервис регистрации и распознавания окон по VM
IViewModelsService
C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
using System.Windows;
using System.Windows.Controls;
 
using Services.Interfaces;
 
namespace HRClient.Services.Interfaces
{
    public interface IViewModelsService
    {
        Window GetWindow(IBaseViewModel viewModel);
        ContentControl GetControl(IBaseViewModel viewModel);
        IViewModelsService Register<TViewModelType, TViewType>()
            where TViewType : ContentControl, new()
            where TViewModelType : IBaseViewModel;
    }
}
ViewModelsService
C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
using System;
using System.Collections.Generic;
using System.Windows;
using System.Windows.Controls;
 
using HRClient.Services.Interfaces;
 
using Services.Interfaces;
 
namespace HRClient.Services
{
    public class ViewModelsService : IViewModelsService
    {
        private readonly Dictionary<Type, Func<ContentControl>> _dict = new Dictionary<Type, Func<ContentControl>>();
 
        public IViewModelsService Register<TViewModelType, TViewType>()
            where TViewType : ContentControl, new()
            where TViewModelType : IBaseViewModel
        {
            _dict[typeof(TViewModelType)] = () => new TViewType();
 
            return this;
        }
 
        public Window GetWindow(IBaseViewModel viewModel)
        {
            var result = GetControl(viewModel);
            if (!(result is Window window))
                throw new Exception($"{result.GetType()} is not window");
            return window;
        }
 
        public ContentControl GetControl(IBaseViewModel viewModel)
        {
            var parentTypes = GetParentTypes(viewModel.GetType());
 
            foreach (var parentType in parentTypes)
            {
                if (_dict.TryGetValue(parentType, out var res))
                    return res();
            }
 
            throw new Exception($"ViewModel {viewModel.GetType().Name} is not registered");
        }
 
        private static IEnumerable<Type> GetParentTypes(Type type)
        {
            if (type == null)
                yield break;
 
            yield return type;
 
            foreach (var i in type.GetInterfaces())
                yield return i;
 
            var currentBaseType = type.BaseType;
 
            while (currentBaseType != null)
            {
                yield return currentBaseType;
                currentBaseType = currentBaseType.BaseType;
            }
        }
    }
}
В App.xaml.cs запускаем все нужные сервисы и сопоставляем VM с их интерфейсами
C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
private static IServiceProvider ConfigureServices()
{
    var services = new ServiceCollection();
 
    services
        .AddSingleton<IMainDA, MainDA>()
        .AddSingleton<IViewModelsService, ViewModelsService>()
        .AddSingleton<IWindowService, WindowService>()
        .AddSingleton<IBackgroundTaskQueue, BackgroundTaskQueue>()
        .AddSingleton<IViewModelFactory, ViewModelFactory>()
        .AddTransient<IMainWindowVM, MainWindowVM>()
        .AddTransient<IEObjectsDialogVM, EObjectsDialogVM>()
        .AddTransient<IEmployeesDialogVM, EmployeesDialogVM>();
 
    return services.BuildServiceProvider();
}
Делаем интерфейс для VM с перечислением нужных свойств
C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
using System.Collections.ObjectModel;
 
using DALibrary.Model;
 
using Services.Interfaces;
 
namespace VModels.DialogsVM.Interfaces
{
    public interface IEObjectsDialogVM : IBaseDialogViewModel
    {
        EObject SelectedEObject { get; set; }
        ObservableCollection<EObject> EObjects { get; }
    }
}
Далее в VM первого окна получаем нужную VM второго окна
C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
private void SelectEObjectExecuted(object obj)
{
    var vm = _viewModelFactory.CreateViewModel<IEObjectsDialogVM>();
 
    if (vm != null)
    {
        _windowService.ShowDialog(vm);
 
        if (vm.DialogResult == true)
        {
            CurrentEObject = vm.SelectedEObject;
        }
    }
}
В общем как-так, осталось перехватить возможные ошибки и всё будет хорошо

Добавлено через 2 минуты
А, забыл WindowService показать
IWindowService
C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
namespace Services.Interfaces
{
    public interface IWindowService
    {
        string ShowOpenFileDialog(string fileName, string defaultExt, string filter);
        void ShowErrorMessage(string message, string caption);
        void ShowInfoMessage(string message, string caption);
        bool ShowQuestionMessage(string message, string caption);
        bool ShowWarningMessage(string message, string caption);
        void ShowWindow(IBaseViewModel viewModel);
        void CloseWindow(IBaseViewModel viewModel);
        bool? ShowDialog(IBaseViewModel viewModel);
    }
}
WindowService
C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
using System;
using System.IO;
using System.Windows;
 
using HRClient.Services.Interfaces;
 
using Microsoft.Win32;
 
using Services.Interfaces;
 
namespace HRClient.Services
{
    internal class WindowService : IWindowService
    {
        private readonly IViewModelsService _viewModelsService;
 
        public WindowService(IViewModelsService viewModelsService)
        {
            _viewModelsService = viewModelsService;
        }
        public Window GetWindow(IBaseViewModel viewModel)
        {
            var window = _viewModelsService.GetWindow(viewModel);
 
            window.DataContext = viewModel;
 
            return window;
        }
 
        public string ShowOpenFileDialog(string fileName, string defaultExt, string filter)
        {
            var openFileDialog = new OpenFileDialog()
            {
                InitialDirectory = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments), "00 - HR Client"),
                FileName = fileName,
                DefaultExt = defaultExt,
                Filter = filter,
                RestoreDirectory = true
            };
 
            return openFileDialog.ShowDialog() == true ? openFileDialog.FileName : null;
        }
 
        public void ShowWindow(IBaseViewModel viewModel)
            => GetWindow(viewModel).Show();
 
        public void CloseWindow(IBaseViewModel viewModel)
            => GetWindow(viewModel).Close();
 
        public bool? ShowDialog(IBaseViewModel viewModel)
            => GetWindow(viewModel).ShowDialog();
 
        public void ShowErrorMessage(string message, string caption)
            => MessageBox.Show(message, caption, MessageBoxButton.OK, MessageBoxImage.Error);
 
        public void ShowInfoMessage(string message, string caption)
            => MessageBox.Show(message, caption, MessageBoxButton.OK, MessageBoxImage.Information);
 
        public bool ShowQuestionMessage(string message, string caption)
        {
            if (MessageBox.Show(message, caption, MessageBoxButton.YesNo, MessageBoxImage.Question) == MessageBoxResult.OK)
            {
                return true;
            }
            else
            {
                return false;
            }
        }
 
        public bool ShowWarningMessage(string message, string caption)
        {
            if (MessageBox.Show(message, caption, MessageBoxButton.YesNo, MessageBoxImage.Warning) == MessageBoxResult.OK)
            {
                return true;
            }
            else
            {
                return false;
            }
        }
    }
}
2
 Аватар для limeniye
1182 / 624 / 160
Регистрация: 19.04.2018
Сообщений: 2,923
15.07.2022, 12:08  [ТС]
Andrey-MSK, честно говоря, схожая реалиазция уже есть в Prism, но круто, что Вы её придумали
1
 Аватар для Andrey-MSK
3392 / 2278 / 388
Регистрация: 14.08.2018
Сообщений: 7,719
Записей в блоге: 4
15.07.2022, 12:11
Цитата Сообщение от limeniye Посмотреть сообщение
что Вы её придумали
Ну не сам придумал, помогали мне
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
inter-admin
Эксперт
29715 / 6470 / 2152
Регистрация: 06.03.2009
Сообщений: 28,500
Блог
15.07.2022, 12:11

Возможна ли утечка памяти в следующем коде
Имеем следующу последовательность высокочастотных операций, требуется оптимизация т к память съедает в течении дня до 1 Гб: ...

Утечка памяти при обновлении текста TextBlock
При каждом тике таймера обновляется текст TextBlock'a. private void Paint(object sender, EventArgs e) { ...

Утечка памяти при большом количестве сообщений
Есть окно сообщения.При новом сообщения создается новое окно(анимировано),старое закрывается(Close).В этом окне есть одно Image.Если много...

Программа не может продолжить работу, так как недостаточно памяти. Утечка в WPF?
В общем, есть у меня контрол, который наследует от Image, воспроизводит анимацию просто сменяя изображения из массива. А сменяются...

HttpWebRequest, расход памяти непомерно больших объемов и , как следствие, утечка памяти
Добрый вечер. Мне была поставлена такая задача. Написать приложение, которая загружает из списка ссылки с сайта и ищет там определенную...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
83
Ответ Создать тему
Новые блоги и статьи
мат медиц модель 30. презентация проекта
anaschu 27.08.2026
хоп хоп хоп хидахоп, а я кладую))
Как у меня протекала болезнь
zorxor 27.08.2026
Здравствуйте, друзья! Эта запись блога предназначена именно для вас - для моих дорогих друзей, которые знали меня лично. Чтобы ответить на вопрос - а что же со мной произошло на самом деле? Я учился. . .
Нашел вот забавное видео о измерениях. Лучшее что я видел на эту тему
kumehtar 26.08.2026
ILETXiw9bMQ Основная суть и тезисы по измерениям: 0D (Нулевое измерение): точка, не имеющая длины, ширины, высоты или объема. Объект не может перемещаться в 0D. 1D (Первое измерение):. . .
[EasyBuilder Pro] Памятка по разработке для панелей Weintek
ФедосеевПавел 26.08.2026
Памятка по разработке для панелей Weintek ВВЕДЕНИЕ Ранее, при реализации проектов основное внимание уделял разработке управляющей программы для контроллера, а панели оператора доставалось время. . .
Модель по догадкам
anaschu 25.08.2026
Прошло две недели. Я уже рассказывал, как разговаривал с сотрудниками у сортировки и как понял, что главная ветка — не про приёмку, а про отбор. Но тогда я думал, что понял механику. На этой неделе я. . .
Запись в регистр сведений независимо от заполненности табличной части
Maks 25.08.2026
Реализация из решения ниже выполнена на нетиповом документе с несколькими табличными частями, разработанного в КА2. Задача: Обеспечить запись документа в регистр сведений независимо от. . .
Ноутбук Альфария
kumehtar 24.08.2026
Встретился тут в сети ноутбук Альфария, примарха Альфа-Легиона. Хотя возможно, это ноутбук Омегона, разумеется. Ну как вам?
Мастера простых решений
DevAlt 23.08.2026
В сишарп стэках winforms, да и wpf существует сложная система связывания источниках данных и элементов формы(текстовые поля и метки), опирается все это на технологию событий и мета. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru