Приложение wpf зависает - загадка массивной утечки памяти

У меня есть приложение mvvm wpf, которое работало должным образом до одного момента, когда оно зависало и приводило к массовой утечке памяти. Файлы решения: Ссылка на решение Google Disk

Приложение использует локальный файл mdf, использует Mahhaps и некоторые дополнительные ссылки (например, для отображения гифок).

Приложение wpf зависает - загадка массивной утечки памяти

Это вызов метода в модели представления, который вызывает проблему, назначение контактов с помощью await создает проблему - это используется в одной другой модели представления, где не возникает никаких проблем, даже здесь он работал нормально до тех пор, пока один момент.

public async  void OnLoad()
        {
            IsRefreshEnabled = false;
            IsRefreshProgressActive = true;
            Contacts =await Task.Run(() => _repository.GetContactsAsync()) ;
            IsRefreshEnabled = true;
            IsRefreshProgressActive = false;
        }

Так визуализируется View

<DataGrid SelectedItem = "{Binding Contact}" AutoGenerateColumns = "True" ItemsSource = "{Binding Path=Contacts, Mode=TwoWay}" Style = "{StaticResource AzureDataGrid}"  x:Name = "dataGridCodeBehind"  Margin = "10,54,521,0" VerticalAlignment = "Top"  HorizontalAlignment = "Stretch" HorizontalContentAlignment = "Stretch" ColumnWidth = "*">
            <DataGrid.ColumnHeaderStyle>
                <Style TargetType = "DataGridColumnHeader">
                    <Setter Property = "FontSize" Value = "10"/>
                </Style>
            </DataGrid.ColumnHeaderStyle>
        </DataGrid>

Я попытался удалить библиотеки для гифок (гифки не отображаются в этом представлении в другом представлении, что не вызывает никаких проблем).

Тот же вызов репозитория - для получения данных контактов, которые у меня есть в одном другом представлении, и это не создает никаких проблем.

Этот вид контактов работал хорошо до внезапно.

Пробовал отлаживать, но отладчик даже не доходит до кода.

После загрузки некоторых данных в базу данных я зависаю.

Замораживание выполняется методом OnLoad из ContactsViewModel - этот вызов репозитория используется еще в одной модели ViewModel, где у него нет никаких проблем - он быстро возвращает данные.

КонтактыViewModel код:

using Digital_Data_House_Bulk_Mailer.Commands;
using Digital_Data_House_Bulk_Mailer.Model;
using Digital_Data_House_Bulk_Mailer.Repository;
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Input;

namespace Digital_Data_House_Bulk_Mailer.ViewModel
{
    class ContactsViewModel : INotifyPropertyChanged
    {
        private Contact _contact;

        private IContactRepository _repository = new ContactRepository();

        public event PropertyChangedEventHandler PropertyChanged = delegate { };

        public static event EventHandler<PropertyChangedEventArgs> StaticPropertyChanged;

        private static void NotifyStaticPropertyChanged(string propertyName)
        {
            if (StaticPropertyChanged != null)
                StaticPropertyChanged(null, new PropertyChangedEventArgs(propertyName));
        }

        public RelayCommand UpdateCommand { get; set; }

        public RelayCommand LoadCommand { get; set; }

        public RelayCommand DeleteCommand { get; set; }

        public RelayCommand DeleteAllContactsCommand { get; set; }

        public RelayCommand RecreateFiltersCommand { get; set; }

        private ObservableCollection<Contact> _contacts;

        public ObservableCollection<Contact> Contacts
        {
            get { return _contacts; }
            set
            {
                _contacts = value;
                PropertyChanged(this, new PropertyChangedEventArgs("Contacts"));
                //used in case of static Contacts property
                //NotifyStaticPropertyChanged("Contacts"); 
            }
        }


        public Contact Contact
        {
            get { return _contact; }
            set
            {
                _contact = value;
                DeleteCommand.RaiseCanExecuteChanged();
                UpdateCommand.RaiseCanExecuteChanged();
                PropertyChanged(this, new PropertyChangedEventArgs("Contact"));
            }
        }

        private bool _isRefreshEnabled=true;
        public bool IsRefreshEnabled
        {
            get { return _isRefreshEnabled; }
            set
            {
                _isRefreshEnabled = value;
                PropertyChanged(this, new PropertyChangedEventArgs("IsRefreshEnabled"));
            }
        }

        private bool _isRefreshProgressActive = false;
        public bool IsRefreshProgressActive
        {
            get { return _isRefreshProgressActive; }
            set
            {
                _isRefreshProgressActive = value;
                PropertyChanged(this, new PropertyChangedEventArgs("IsRefreshProgressActive"));
            }
        }

        public ContactsViewModel()
        {
            DeleteCommand = new RelayCommand(OnDelete, CanDelete);
            UpdateCommand = new RelayCommand(OnUpdate, CanUpdate);
            LoadCommand = new RelayCommand(OnLoad, CanLoad);
            DeleteAllContactsCommand = new RelayCommand(OnDeleteAllContacts, CanDeleteAllContacts);
            RecreateFiltersCommand = new RelayCommand(OnRecreateFilters, CanRecreateFilters);
            OnLoad();
        }

        public bool CanRecreateFilters()
        {
            return true;
        }

        public async void OnRecreateFilters()
        {
            IsRefreshProgressActive = true;
            await Task.Run(() => _repository.ResetFilters());
            IsRefreshProgressActive = false;
        }

        public async void OnDeleteAllContacts()
        {
            MessageBoxResult messageBoxResult = System.Windows.MessageBox.Show("Are you sure?", "DELETE ALL EXISTING CONTACTS", System.Windows.MessageBoxButton.YesNo);
            if (messageBoxResult == MessageBoxResult.Yes)
            {
                IsRefreshProgressActive = true;
                await Task.Run(() => _repository.DeleteAllContacts());
                IsRefreshProgressActive = false;
            }
        }

        public bool CanDeleteAllContacts()
        {
            return true;
        }


        private void OnDelete()
        {
            MessageBoxResult messageBoxResult = System.Windows.MessageBox.Show("Are you sure?", "Delete Contact Confirmation", System.Windows.MessageBoxButton.YesNo);
            if (messageBoxResult == MessageBoxResult.Yes)
            {
                _repository.DeleteContactAsync(Contact);
                Contacts.Remove(Contact);
            }
        }

        private bool CanDelete()
        {          
            if (Contact != null )
            {
                return true;
            }
            return false;
        }

        private  void OnUpdate()
        {
             _repository.AddContactAsync(Contact);

        }

        private bool CanUpdate()
        {
            if (Contact != null )
            {
                return true;
            }
            return false;
        }


        public async  void OnLoad()
        {
            IsRefreshEnabled = false;
            IsRefreshProgressActive = true;
            Contacts =await Task.Run(() => _repository.GetContactsAsync()) ;
            IsRefreshEnabled = true;
            IsRefreshProgressActive = false;
        }

        private  ObservableCollection<Contact> GetContactsAsync()
        {
            return _repository.GetContactsAsync();
        }

        public bool CanLoad()
        {
            return true;
        }

    }
}

ContactRepository класс:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Digital_Data_House_Bulk_Mailer.Model;
using System.Data.Entity;
using System.Collections.ObjectModel;
using System.Data.Entity.Migrations;
using System.Collections;
using System.Data.Entity.Core.Objects;
using System.Data.SqlClient;

namespace Digital_Data_House_Bulk_Mailer.Repository
{
    class ContactRepository : IContactRepository
    {
        digital_datahouse_bulk_mailerEntities db = null;

        public ContactRepository()
        {
            db = new digital_datahouse_bulk_mailerEntities();
        }

        public string SELECT_ALL { get { return "Select All"; } private set { } }


        public  ObservableCollection<StateFilter> GetStates()
        {

            ObservableCollection<StateFilter> stateFilters = new ObservableCollection<StateFilter>();

            foreach (StateFilter state in db.StateFilters.ToList() )
            {
                db.Entry<StateFilter>(state).Reload();
                stateFilters.Add(state);
            }



            return stateFilters;
        }

        public ObservableCollection<CountyFilter> GetCounties()
        {
            ObservableCollection<CountyFilter> countyFilters = new ObservableCollection<CountyFilter>();

            foreach (CountyFilter county in db.CountyFilters.ToList())
            {
                db.Entry<CountyFilter>(county).Reload();
                countyFilters.Add(county);
            }

            return countyFilters;
        }

        public ObservableCollection<GenderFilter> GetGenders()
        {
            ObservableCollection<GenderFilter> genderFilters = new ObservableCollection<GenderFilter>();

            foreach (GenderFilter gender in db.GenderFilters.ToList())
            {
                db.Entry<GenderFilter>(gender).Reload();
                genderFilters.Add(gender);
            }

            return genderFilters;
        }

        public ObservableCollection<IndustryFilter> GetIndustries()
        {
            ObservableCollection<IndustryFilter> industryFilters = new ObservableCollection<IndustryFilter>();

            foreach (IndustryFilter industry in db.IndustryFilters.ToList())
            {
                db.Entry<IndustryFilter>(industry).Reload();
                industryFilters.Add(industry);
            }

            return industryFilters;
        }

        public ObservableCollection<IsContactedFilter> GetIsContacted()
        {
            ObservableCollection<IsContactedFilter> isContactedFilters = new ObservableCollection<IsContactedFilter>();

            foreach (IsContactedFilter isContacted in db.IsContactedFilters.ToList())
            {
                db.Entry<IsContactedFilter>(isContacted).Reload();
                isContactedFilters.Add(isContacted);
            }

            return isContactedFilters;
        }

        public ObservableCollection<SicCodeDescriptionFilter> GetSicCodeDescriptions()
        {
            ObservableCollection<SicCodeDescriptionFilter> sicCodeDescriptionFilters = new ObservableCollection<SicCodeDescriptionFilter>();

            foreach (SicCodeDescriptionFilter sicCodeDescriptionFilter in db.SicCodeDescriptionFilters.ToList())
            {
                db.Entry<SicCodeDescriptionFilter>(sicCodeDescriptionFilter).Reload();
                sicCodeDescriptionFilters.Add(sicCodeDescriptionFilter);
            }

            return sicCodeDescriptionFilters;
        }



        public void AddContactAsync(Contact contact)
        {
            if (contact != null)
            {
                db.Contacts.AddOrUpdate(contact);
                db.SaveChangesAsync();
            }
        }

        public void DeleteContactAsync(Contact contact)
        {
            if (contact != null)
            {
                db.Contacts.Remove(contact);
                db.SaveChangesAsync();
            }
        }

        public void UpdateContactAsync(Contact contact)
        {
            if (contact != null)
            {
                db.Contacts.AddOrUpdate(contact);
                db.SaveChangesAsync();
            }
        }

        public ObservableCollection<Contact> GetContactsAsync()
        {

            db = new digital_datahouse_bulk_mailerEntities();

            ObservableCollection<Contact> contacts = new ObservableCollection<Contact>();

            foreach (var contact in db.Contacts.ToList())
            {
                contacts.Add(contact);
            }
            return contacts;
        }

        public ObservableCollection<Contact> FilterContacts(ObservableCollection<StateFilter> states, ObservableCollection<CountyFilter> counties, 
            ObservableCollection<GenderFilter> genders, ObservableCollection<IndustryFilter> industries, ObservableCollection<IsContactedFilter> contacted, 
            ObservableCollection<SicCodeDescriptionFilter> codes, bool hasWebsite)
        {

            db = new digital_datahouse_bulk_mailerEntities();

            ObservableCollection<Contact> filteredContacts = new ObservableCollection<Contact>();

            string[] stateArray = (from s in states where s.IsChecked==true select s.State).ToArray();
            string[] countyArray= (from c in counties where c.IsChecked==true select c.County).ToArray();
            string[] genderArray= (from g in genders where g.IsChecked==true select g.Gender).ToArray();
            string[] industryArray = (from i in industries where i.IsChecked==true select i.Industry).ToArray();
            string[] contactedArray = (from c in contacted where c.IsChecked==true select c.IsContacted.ToString()).ToArray();
            string[] sicCodeArray = (from c in codes where c.IsChecked==true select c.SicCodeDescription).ToArray();

            var contacts=(from c in db.Contacts
                          where
                          stateArray.Contains(c.State) &&
                          countyArray.Contains(c.County) &&
                          genderArray.Contains(c.Gender) &&
                          industryArray.Contains(c.Industry) &&
                          contactedArray.Contains(c.IsContacted) &&
                          sicCodeArray.Contains(c.SIC_Code_Description)

                          select c).ToList();

            foreach (Contact contact in contacts)
            {
                if (hasWebsite==true)
                {
                    if (!String.IsNullOrEmpty(contact.WebSite))
                    {
                        filteredContacts.Add(contact);
                    }
                }
                else
                {
                    filteredContacts.Add(contact);
                }

            }

            return filteredContacts;
        }

        public void AddContactsRange(ObservableCollection<Contact> contacts)
        {

                db.Contacts.AddRange(contacts);
                db.SaveChanges();

        }

        public void ResetFilters()
        {
            ResetStates();
            ResetCounties();
            ResetIsContactedFilters();
            ResetGenders();
            ResetIndustries();
            ResetSicFilters(); 

        }

        private void ResetStates()
        {
            db.Database.ExecuteSqlCommand("TRUNCATE TABLE [StateFilter]");

            db = new digital_datahouse_bulk_mailerEntities();

            List<StateFilter> stateFilters = new List<StateFilter>();

            var states = (
                from c in db.Contacts
                select c.State

                ).Distinct().ToList();

            foreach (var stateName in states)
            {
                StateFilter state = new StateFilter();
                state.State = stateName;
                state.IsChecked = true;
                stateFilters.Add(state);

            }


            db.StateFilters.AddRange(stateFilters);
            db.SaveChanges();

        }

        public void DeleteAllContacts()
        {
            db.Database.ExecuteSqlCommand("TRUNCATE TABLE [Contact]");           
            db = new digital_datahouse_bulk_mailerEntities();   
        }

        private void ResetCounties()
        {
            db.Database.ExecuteSqlCommand("TRUNCATE TABLE [CountyFilter]");
            db = new digital_datahouse_bulk_mailerEntities();

            List<CountyFilter> countyFilters = new List<CountyFilter>();

            var counties = (
                from c in db.Contacts
                select c.County

                ).Distinct().ToList();

            foreach (var countyName in counties)
            {
                CountyFilter county = new CountyFilter();
                county.County = countyName;
                county.IsChecked = true;
                countyFilters.Add(county);
            }

            db.CountyFilters.AddRange(countyFilters);
            db.SaveChanges();
        }

        private void ResetGenders()
        {
            db.Database.ExecuteSqlCommand("TRUNCATE TABLE [GenderFilter]");
            db = new digital_datahouse_bulk_mailerEntities();

            List<GenderFilter> genderFilters = new List<GenderFilter>();

            var genders = (
                from c in db.Contacts
                select c.Gender

                ).Distinct().ToList();

            foreach (var genderName in genders)
            {
                GenderFilter gender = new GenderFilter();
                gender.Gender = genderName;
                gender.IsChecked = true;
                genderFilters.Add(gender);
            }

            db.GenderFilters.AddRange(genderFilters);
            db.SaveChanges();
        }

        private void ResetIndustries()
        {
            db.Database.ExecuteSqlCommand("TRUNCATE TABLE [IndustryFilter]");
            db = new digital_datahouse_bulk_mailerEntities();

            List<IndustryFilter> industryFilters = new List<IndustryFilter>();

            var industries = (
                from c in db.Contacts
                select c.Industry

                ).Distinct().ToList();

            foreach (var industryName in industries)
            {
                IndustryFilter industry = new IndustryFilter();
                industry.Industry = industryName;
                industry.IsChecked = true;
                industryFilters.Add(industry);
            }

            db.IndustryFilters.AddRange(industryFilters);
            db.SaveChanges();
        }

        private void ResetIsContactedFilters()
        {
            db.Database.ExecuteSqlCommand("TRUNCATE TABLE [IsContactedFilter]");
            db = new digital_datahouse_bulk_mailerEntities();

            List<IsContactedFilter> isContactedFilters = new List<IsContactedFilter>();

            var isContacted = (
                from c in db.Contacts
                select c.IsContacted

                ).Distinct().ToList();

            foreach (var contactedName in isContacted)
            {
                IsContactedFilter contacted = new IsContactedFilter();
                contacted.IsContacted = contactedName;
                contacted.IsChecked = true;
                isContactedFilters.Add(contacted);
            }

            db.IsContactedFilters.AddRange(isContactedFilters);
            db.SaveChanges();
        }

        private void ResetSicFilters()
        {
            db.Database.ExecuteSqlCommand("TRUNCATE TABLE [SicCodeDescriptionFilter]");
            db = new digital_datahouse_bulk_mailerEntities();

            List<SicCodeDescriptionFilter> sicFilters = new List<SicCodeDescriptionFilter>();

            var sics = (
                from c in db.Contacts
                select c.SIC_Code_Description

                ).Distinct().ToList();

            foreach (var sic in sics)
            {
                SicCodeDescriptionFilter sicCode = new SicCodeDescriptionFilter();
                sicCode.SicCodeDescription = sic;
                sicCode.IsChecked = true;
                sicFilters.Add(sicCode);
            }

            db.SicCodeDescriptionFilters.AddRange(sicFilters);
            db.SaveChanges();
        }

        public void UpdateIsContactedInformation(Contact contact)
        {
            db = new digital_datahouse_bulk_mailerEntities();

            contact.IsContacted = "True";
            contact.MessageDateSent = DateTime.Today;

            db.Contacts.AddOrUpdate(contact);
            db.SaveChanges();
        }
    }
}

Это представление, которое использует ViewModel, оно называется ContactsView - это представление включено в MainWindow, как и другие представления.

КонтактыПросмотр:

<UserControl x:Class = "Digital_Data_House_Bulk_Mailer.View.ContactsView"
         xmlns = "http://schemas.microsoft.com/winfx/2006/xaml/presentation"
         xmlns:x = "http://schemas.microsoft.com/winfx/2006/xaml"
         xmlns:mc = "http://schemas.openxmlformats.org/markup-compatibility/2006" 
         xmlns:d = "http://schemas.microsoft.com/expression/blend/2008" 
         xmlns:local = "clr-namespace:Digital_Data_House_Bulk_Mailer.View"
         xmlns:Controls = "clr-namespace:MahApps.Metro.Controls;assembly=MahApps.Metro"
         xmlns:model = "clr-namespace:Digital_Data_House_Bulk_Mailer.ViewModel"
         mc:Ignorable = "d" 
         d:DesignHeight = "300" d:DesignWidth = "300">
<UserControl.DataContext>
    <model:ContactsViewModel/>
</UserControl.DataContext>
<Grid Margin = "0,0,-690,-36" >
    <Grid.ColumnDefinitions>
        <ColumnDefinition Width = "61*"/>
        <ColumnDefinition Width = "10*"/>
    </Grid.ColumnDefinitions>
    <Button  Style = "{StaticResource AccentedSquareButtonStyle}" Command = "{Binding DeleteCommand}" Controls:TextBoxHelper.ClearTextButton = "True" x:Name = "delete" Content = "DELETE" HorizontalAlignment = "Left" Margin = "115,21,0,0" VerticalAlignment = "Top"  Width = "100" RenderTransformOrigin = "0.267,0.519"/>
    <Button  Style = "{StaticResource AccentedSquareButtonStyle}" Command = "{Binding UpdateCommand}" Controls:TextBoxHelper.ClearTextButton = "True" x:Name = "update" Content = "add / update" HorizontalAlignment = "Left" Margin = "10,21,0,0" VerticalAlignment = "Top"  Width = "100" RenderTransformOrigin = "0.267,0.519"/>
    <Button  Style = "{StaticResource AccentedSquareButtonStyle}"  Controls:TextBoxHelper.ClearTextButton = "True" x:Name = "bulk_import" Content = "import new data" HorizontalAlignment = "Left" Margin = "220,21,0,0" VerticalAlignment = "Top"  Width = "110" RenderTransformOrigin = "0.267,0.519" Click = "bulk_import_Click"/>
    <DataGrid SelectedItem = "{Binding Contact}" AutoGenerateColumns = "True" ItemsSource = "{Binding Path=Contacts, Mode=TwoWay}" Style = "{StaticResource AzureDataGrid}"  x:Name = "dataGridCodeBehind"  Margin = "10,54,521,0" VerticalAlignment = "Top"  HorizontalAlignment = "Stretch" HorizontalContentAlignment = "Stretch" ColumnWidth = "*">
        <DataGrid.ColumnHeaderStyle>
            <Style TargetType = "DataGridColumnHeader">
                <Setter Property = "FontSize" Value = "10"/>
            </Style>
        </DataGrid.ColumnHeaderStyle>
    </DataGrid>
    <Button IsEnabled = "{Binding IsRefreshEnabled}" Style = "{StaticResource AccentedSquareButtonStyle}" Command = "{Binding LoadCommand}" x:Name = "refreshData" Content = "Refresh Contacts" HorizontalAlignment = "Left" Height = "22" Margin = "335,21,0,0" VerticalAlignment = "Top" Width = "114"/>
    <Controls:ProgressRing IsActive = "{Binding IsRefreshProgressActive}" Foreground = "{DynamicResource AccentColorBrush}" Margin = "720,0,0,0" RenderTransformOrigin = "-2.889,0.463" HorizontalAlignment = "Left" VerticalAlignment = "Top" Height = "50" Width = "50"/>
    <Button x:Name = "deleteContacts" Command = "{Binding DeleteAllContactsCommand}" Style = "{StaticResource AccentedSquareButtonStyle}" Content = "Delete All Contacts" HorizontalAlignment = "Left" Height = "22" Margin = "454,21,0,0" VerticalAlignment = "Top" Width = "114"/>
    <Button x:Name = "recreateFilters" Command = "{Binding RecreateFiltersCommand}" Content = "Recreate TO MAIL Filters" HorizontalAlignment = "Left" Style = "{StaticResource AccentedSquareButtonStyle}" Height = "22" Margin = "573,21,0,0" VerticalAlignment = "Top" Width = "142"/>

</Grid>

Очень плохо то, что когда я пытаюсь отладить, он даже не переходит к вызову кода - метода. Пытался также использовать некоторые инструменты профилирования, но я не пришел к какому-либо выводу, что вызывает эту проблему с зависанием ...

Когда я запускаю запрос к базе данных из редактора базы данных, я получаю мгновенные результаты.

Я также использую отчет SSRS в приложении, отображаемом с помощью ReportViewer - он также отлично работает и возвращает те же данные - он отображается в отдельном представлении.

В одном из представлений я показываю GIF-анимацию с использованием библиотеки WpfAnimatedGif - я попытался удалить эту ссылку, чтобы посмотреть, не вызывает ли это проблема, но это не значит, что замораживание продолжается ...

Я также попытался переписать свой класс репозитория, чтобы использовать команду using для создания нового экземпляра db для каждого метода, но проблема не в этом.

Файлы решения: Ссылка на решение Google Disk

1. Почему вы используете асинхронный метод в задаче (Task.Run(() => _repository.GetContactsAsync()))? 2. Зачем загружаете контакты все? 3. Размер базы данных не имеет большого значения, о скольких записях идет речь? Он все еще зависает, когда вы загружаете меньше данных?

Gert Arnold 19.05.2018 23:41

Несколько дней назад я смог загрузить 100 000 данных без каких-либо проблем, теперь я попытался загрузить 10 контактов, и они не зависают, когда я загружаю 1000, они зависают. Я попытался удалить async и await, и это не имеет значения - он снова зависает. A также попытался удалить все стили из этого представления, все равно без разницы. Это может быть проблема с базой данных, возможно, файл каким-то образом поврежден. Странно то, что у меня есть представление, в котором я получаю одни и те же данные, и они загружаются нормально ...

Jovo Krneta 20.05.2018 00:42

A также уменьшил размер локального файла mdf, запустив DBCC SHRINKDATABASE (0); GO, опять приложение зависает

Jovo Krneta 20.05.2018 00:55

Подключите профилировщик к своей базе данных и посмотрите, что происходит, когда вы запускаете замораживание. В вашем коде ничего не выделяется, но создание DbContexts с последующим возвратом сущностей определенно будет неэффективным. Я бы рекомендовал не возвращать Entities в ваше представление, вместо этого создайте модель просмотра, выберите свои объекты и заполните модели просмотра, чтобы вернуть только те данные, которые вам нужны. Используя фильтрацию, по возможности, составляйте условия в свой Linq, а не перебирайте список сущностей.

Steve Py 20.05.2018 01:26

@ Steve Py - поскольку я использую локальный файл mdf, я не уверен, как подключить профилировщик студии управления сервером sql для мониторинга локального файла mdf db ...

Jovo Krneta 20.05.2018 01:39

Я повторно подключил приложение к базе данных Sql Server и запустил профилировщик на базе данных, не возвращает никаких операторов sql после зависания приложения. Приложение зависает независимо от того, использует ли он локальный файл db или sql-сервер ... Так что проблема здесь не в этом

Jovo Krneta 20.05.2018 10:51

Я думаю, это связано с неправильными асинхронными методами. Как я уже сказал в своем первом комментарии, паттерн Task.Run странный. Кроме того, async void - это антипаттерн. Хотя бы вернуть Task. Зависание при отсутствии доступа к базе данных указывает на взаимоблокировку потоков.

Gert Arnold 20.05.2018 11:33

Я попробовал обе вещи, чтобы вернуть задачу вместо void, а также попробовал второй вариант полного удаления async и await, сделав вызовы synh, без изменений.

Jovo Krneta 20.05.2018 11:37

Я включил папку решения, заархивированную на диске Google, со всеми необходимыми элементами для воссоздания проблемы, перейдите в раздел «Настройка данных», нажмите «Импорт», сначала выберите файл Alaska_short для импорта, нажав «Выбрать файл», установите оба флажка, для разделителя выберите запятую, нажмите «Загрузить» данные для сопоставления, сопоставьте хотя бы название компании и адрес электронной почты с GenericCompanyEmailAddress, нажмите «Импорт», когда закончите, закройте окно для импорта и нажмите кнопку «Обновить». Все будет хорошо. Повторите процесс с файлом Alaska_large.zip, и приложение зависнет.

Jovo Krneta 20.05.2018 12:39

Список контактов заполняется из базы данных, похоже, проблема не в этом, я также попытался воссоздать весь частичный ContactsView с нуля - замораживание все еще продолжается.

Jovo Krneta 21.05.2018 12:57

Когда я ограничиваю загрузку до 50 контактов, он загружает данные через 10 секунд, после того как я увеличиваю количество записей, которые он замораживает, я также пытался вручную определить только несколько столбцов для отображения, но сетка снова зависает. Похоже, это проблема рендеринга сетки ...

Jovo Krneta 21.05.2018 14:42
Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
8
11
606
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Ответ принят как подходящий

Я наконец решил эту проблему. Мне нужно было добавить свойство Height = "500" в сетку данных.

Удаление свойства Height приводит к зависанию DataGrid при отображении более 50 строк в моем случае. С добавленной высотой он загружает 5000 записей менее чем за секунду.

Просто предложение.

Я работал с сеткой с большими списками. Я бы посоветовал вам включить виртуализацию, и это может улучшить производительность пользовательского интерфейса.

вы можете обратиться по этой ссылке для получения дополнительной информации

https://docs.microsoft.com/en-us/dotnet/framework/wpf/getting-started/whats-new#new-features-for-the-virtualizingpanel

Другие вопросы по теме