This is a migrated thread and some comments may be shown as answers.

Out of memory

12 Answers 247 Views
GridView
This is a migrated thread and some comments may be shown as answers.
Gianfranco
Top achievements
Rank 1
Gianfranco asked on 18 Dec 2018, 08:35 PM

Goodmorning everyone
I have a really difficult problem to solve for myself, as well as a series of questions to cover a series of doubts.
Accordingly:
app wpf for windows 10 developed with visual studio 2017
.Net Framework 4.5.2
important:
the anomaly I am about to describe does not occur in the development environment, but only with .exe compiled.(debug or release)

my app reads several bytes per second via UTP coming from a microprocessor.
For the reception I created a separate thread.
to view the data received in the xlm graphical interface I followed instructions inside the reception thread as, for example:
Dispatcher.BeginInvoke ((Action) (() => lblPercWorkPhaseInProcessDone.Content = percTotalDone.ToString () + "%"));

where lblPercWorkPhaseInProcessDone is a label.

at each microprocessor event, a table SQL is also stored where I store the historical events of the industrial plant.

therefore, always at each event (data received by the microprocessor in the separate thread) refresh (every about a second) the datagrid containing the events table, with the following instruction:

Dispatcher.BeginInvoke ((Action) (() => RadGridViewWorkPhaseInProgressOnDashBoard.ItemsSource = workPhaseInProgressService.GetByWorkPhaseForOrderId (workPhaseForOrderIdInProcess)));

where

GetByWorkPhaseForOrderId is a method of its class with entity framework:

public List <WorkPhaseInProgress> GetByWorkPhaseForOrderId (int id)
        {
            try {
                using (WIPDBContext db = new WIPDBContext ())
                {
                    var Attachment = db.WorkPhasesInProgress.Where (x => x.WorkPhaseForOrderId == id) .OrderByDescending (x => x.WorkPhaseInProgressId) .ToList ();
                    return Attachment;

                }
            }
            catch (Exception x)
            {
               
                throw x;
            }
        }

after about 5 or 6 hours of operation the program comes out generating an error in the windows log:
EventData

Application: WIP.exe Framework version: v4.0.30319 Description: The process was terminated due to an unhandled exception. Exception information: System.OutOfMemoryException in WIP.Service.WorkPhaseInProgressService.GetByWorkPhaseForOrderId (Int32) in WIP.MainWindow. <RefreshGridWorkInProgress> b__188_0 () in System.Windows.Threading.ExceptionWrapper.InternalRealCall (System.Delegate, System.Object, Int32 ) in System.Windows.Threading.ExceptionWrapper.TryCatchWhen (System.Object, System.Delegate, System.Object, Int32, System.Delegate) in System.Windows.Threading.DispatcherOperation.InvokeImpl () in System.Windows.Threading.DispatcherOperation .InvokeInSecurityContext (System.Object) in System.Threading.ExecutionContext.RunInternal (System.Threading.ExecutionContext, System.Threading.ContextCallback, System.Object, Boolean) in System.Threading.ExecutionContext.Run (System.Threading.ExecutionContext, System .Threading.ContextCallback, System.Object, Boolean) in System.Threading.ExecutionContext.Run (System.Threading.ExecutionContext, System.Threading.ContextCallback, System.Object) in MS.Internal.CulturePreservingEx ecutionContext.Run (MS.Internal.CulturePreservingExecutionContext, System.Threading.ContextCallback, System.Object) in System.Windows.Threading.DispatcherOperation.Invoke () in System.Windows.Threading.Dispatcher.ProcessQueue () in System.Windows.Threading .Dispatcher.WndProcHook (IntPtr, Int32, IntPtr, IntPtr, Boolean ByRef) in MS.Win32.HwndWrapper.WndProc (IntPtr, Int32, IntPtr, IntPtr, Boolean ByRef) in MS.Win32.HwndSubclass.DispatcherCallbackOperation (System.Object) in System.Windows.Threading.ExceptionWrapper.InternalRealCall (System.Delegate, System.Object, Int32) in System.Windows.Threading.ExceptionWrapper.TryCatchWhen (System.Object, System.Delegate, System.Object, Int32, System.Delegate) in System.Windows.Threading.Dispatcher.LegacyInvokeImpl (System.Windows.Threading.DispatcherPriority, System.TimeSpan, System.Delegate, System.Object, Int32) in MS.Win32.HwndSubclass.SubclassWndProc (IntPtr, Int32, IntPtr, IntPtr) in MS.Win32.UnsafeNativeMethods.DispatchMessage (System.Windows.Interop.M SG ByRef) in System.Windows.Threading.Dispatcher.PushFrameImpl (System.Windows.Threading.DispatcherFrame) in System.Windows.Threading.Dispatcher.PushFrame (System.Windows.Threading.DispatcherFrame) in System.Windows.Application.RunDispatcher ( System.Object) in System.Windows.Application.RunInternal (System.Windows.Window) in System.Windows.Application.Run (System.Windows.Window) in System.Windows.Application.Run () in WIP.App.Main ()

 

 

the records in the table are about 10,000, for now, but will be destined to increase a lot.

my questions are:
It is correct to display my data from a separate thread with the method Dispatcher.BeginInvoke ?

why does not this happen in the development environment?

 

I hope I have explained the scenario well.

How can I solve?
thank you in advance

 

12 Answers, 1 is accepted

Sort by
0
Pawel
Top achievements
Rank 1
answered on 21 Dec 2018, 08:14 AM

How to solve your problem.

Since you have memory problems after 5 hours so maybe you have some memory leaks, have you checked it? Download for Ex DotMemory from resharper, or .Net mermoryprofiler (https://memprofiler.com/) and check it.

 

If you think that C# will always take care of your memory you see that it is not true. There are many possible leaks i WPF, and c# - bindingleaks, event hadlers leaks ..

Read in the internet how to find memory leaks. More less is just running profiler making snapshot and performing suspicious operation and then making snapshot. 

 

Btw tip for me about entity. If you want to improve performance use asnotracking

var Attachment = db.WorkPhasesInProgress.AsNoTracking().Where (x => x.WorkPhaseForOrderId == id) .OrderByDescending (x => x.WorkPhaseInProgressId) .ToList ();

 

 

0
Martin Ivanov
Telerik team
answered on 21 Dec 2018, 02:45 PM
Hi guys,

First, I want to thank Pawel for joining this forum because its description is the way to go with the investigation of the issue.

Here are also my thoughts on this. The issue is probably caused by one or more memory leaks in the application or the RadGridView control. It seems like something is holding a reference to some of your objects that should not be in memory and after some time the application's memory depletes. However, without reproducing this I cannot tell what happens. To find out the reason behind this behavior you can use a memory profiling tool like the listed by Pawel. This way you can see what objects are no longer used but still live in the memory, and track down the issue. 

As for the concrete questions:
  • It is correct to display my data from a separate thread with the method Dispatcher.BeginInvoke ?

    Yes. The WPF framework doesn't allow you to touch the UI on a thread different than the main UI thread. But this doesn't restrict you to work with your data on a separate thread. The only required is to dispatch the corresponding action to the main UI thread.

  • Why does not this happen in the development environment?

    I can't tell. A memory leak most probably, but you need to investigate this further. If you track this down to the RadGridView control, you can prepare an isolated project showing the issue and send it to the support team via the ticketing system.

I hope this information helps.

Regards,
Martin Ivanov
Progress Telerik
Get quickly onboarded and successful with your Telerik and/or Kendo UI products with the Virtual Classroom free technical training, available to all active customers. Learn More.
0
Gianfranco
Top achievements
Rank 1
answered on 21 Dec 2018, 04:32 PM
Thanks to all of you who have answered me
With your advice, I immediately went to work.
Unfortunately I am very worried because the software must go into production as soon as possible.
I'll keep you up-to-date.
Thanks again
0
Gianfranco
Top achievements
Rank 1
answered on 26 Dec 2018, 10:45 PM
Hi everybody
in a week I'll have to deliver my software.
as I said in the previous post, only out of the client occurs the outofmemory error.
so it is impossible for me to follow your tracks to find the cause.
for now I thought of proceeding to step:

1- delete all Dispatcher.BeginInvoke ((Action) (() =>....
and refresh the data on the screen with a timer;
that is, when you need to update the data on the screen, I enable a timer that trivially assigns the value to the xaml interface.

2-possible "defect" of windows 10? I will replace the client's PC.

3-I will disable all the parts that interact from the thread to the xaml interface and then enable one by one with the hope of identifying the one that generates the error.

4- replace telerik RadGridview with a simple gridview?

Finally I would like to ask an important question for me:
I decided to create wpf apps for my industrial applications (robots and similar machines).
Did I make the wrong choice?
Perhaps the simple desktop application was better?

thanks for everything
0
Gianfranco
Top achievements
Rank 1
answered on 26 Dec 2018, 10:50 PM
for "simple desktop application" I meant winform application !!

thanks for everything
0
Gianfranco
Top achievements
Rank 1
answered on 26 Dec 2018, 10:51 PM

I correct my last post

For "simple desktop application" I meant winform application !!

thanks for everything

0
Martin Ivanov
Telerik team
answered on 27 Dec 2018, 07:03 AM
Hello Gianfranco,

I hope that you will fix the issue on your side soon. As for your last question, me personally, not familiar with the industry so I can't give you an accurate answer. However, my general opinion on what technology should be used is that it depends. More specifically it depends on the concrete requirements and on the developer preferences. 

If you have your doubts about WPF I could advise you to invest some time and research what are the alternatives based on your requirement. Then compare the found information and review your choice.

Anyway, WPF is a great UI desktop technology, especially if you want to make very rich and easily maintainable UI.

Regards,
Martin Ivanov
Progress Telerik
Get quickly onboarded and successful with your Telerik and/or Kendo UI products with the Virtual Classroom free technical training, available to all active customers. Learn More.
0
Pawel
Top achievements
Rank 1
answered on 27 Dec 2018, 10:21 AM

It is totally possible to follow our tracks to find out the reason :), if you have not much time then focus ^^ and try to solve it.

To be honest it is not really possible that the application is leaking on client side only. I bet that client has different PC/ system specification, less ram and for ex 32bit system - so it means that the application needs to consume less RAM to crash.

 

Nevermind ^^, have you ever heard about memory dumps? If you can only reproduce problem on client side then take debug binaries to client side do leaking operations, observe ram comsumption. Dont allow app to crash and take memory dump of windows process. With this file you can find the problem with programs i have recommended you.

 

0
Gianfranco
Top achievements
Rank 1
answered on 27 Dec 2018, 11:13 AM
Thanks Pawel for your interest in my problem ..
The project involves the use of my software on 15 pc all the same connected to the respective microprocessors of industrial plants.
The PCs are all I5 with Windows 10 PRO 64 bit with 8GB RAM.
My pc where it continues to work is an I7 with 16 GB ram, always Windows 10 PRO.

I managed to try on my pc for two days and two consecutive nights without ever interrupting.

Through the customer's Wifi network I support a server with Microsoft SQL express 2016.

The concept of memory loss is new to me .. so I'm documenting and comparing with my colleagues, certainly more prepared than me.
sure is that, I must give answers and solutions to the customer as soon as possible.
Finding the exact point where the program comes out for now is really difficult for me .... obviously not impossible ....
I must stay calm and reflect to act as you advise me.

for last
I compiled the 32-bit project.

as soon as I have news, I will update you
Thanks again
0
Gianfranco
Top achievements
Rank 1
answered on 18 Jan 2019, 03:26 PM

Goodmorning everyone
I found the cause of the "OutOfMemory" error:  RadGridView

 
As I explained in previous posts, my software performs a select in the SQL database (about 2 times per second) to refresh the data by displaying it in a RadGridView.
Initially I had modified a select of the whole DB with only the last 13 records, in order to fill only the form; with the hope of avoiding the overload of the PC and the network.
nevertheless he always gave error.
in details:
service to extract data
 public List <WorkPhaseInProgress> GetByWorkPhaseForOrderIdTOP13 (int id)
        {
            try
            {
                using (WIPDBContext db = new WIPDBContext ())
                {
                    var Attachment = db.WorkPhasesInProgress.AsNoTracking (). Where (x => x.WorkPhaseForOrderId == id) .Take (13) .OrderByDescending (x => x.WorkPhaseInProgressId) .ToList ();
                    return Attachment;

                }
            }
            catch (Exception x)
            {
                 throw x;
            }
        }


then to display them in RadGridView:
                RadGridViewWorkPhaseInProgressOnDashBoard.ItemsSource = workPhaseInProgressService.GetByWorkPhaseForOrderIdTOP13 (workPhaseForOrderIdInProcess);

while
I replaced the RadGridView with DataGrid and it is already 4 days since the error has not occurred.
I'm not at all happy with the solution.

But, for now, I put the client in a position to work.

RadGridView version: 2018.3.911.45
Runtime version: v4.0.30319

 

question:
How can I prevent RadGridView from giving an error?
I absolutely have to solve it, also because I will have to use it in many similar projects always for industrial automation.

Thanks!

for scruple, I report both the code for using the RadGridView and the Xaml code:

  RadGridViewWorkPhaseInProgressOnDashBoard.EnableRowVirtualization = true;
  RadGridViewWorkPhaseInProgressOnDashBoard.IsSynchronizedWithCurrentItem = false;
  RadGridViewWorkPhaseInProgressOnDashBoard.ItemsSource = workPhaseInProgressService.GetByWorkPhaseForOrderIdTOP13 (workPhaseForOrderIdInProcess);

Xaml code

                <telerik:RadGridView x:Name="RadGridViewWorkPhaseInProgressOnDashBoard" Language="Ita" IsLocalizationLanguageRespected="False" telerik:StyleManager.Theme="Summer"
Focusable="False"
                             CanUserSelect="True"     
Margin="10,342,10,-137"
RowHeight="45"
                             EnableRowVirtualization="True"    
ItemsSource="{Binding WorkPhasesInProgress}"
IsSynchronizedWithCurrentItem="True"
                             IsManipulationEnabled="False"
                             IsReadOnly="True"
                             ShowColumnSortIndexes="False"
AutoGenerateColumns="False"
CanUserFreezeColumns="False"
                             IsFilteringAllowed="False"        
                             ShowGroupPanel="False"
                             ShowSearchPanel="False"
CanUserResizeColumns="False">
                    <telerik:RadGridView.Columns>
                        <telerik:GridViewDataColumn Header="Operatore" HeaderTextAlignment="Center"
DataMemberBinding="{Binding Initial}"  TextAlignment="Center"  Width="200"  />
                        <telerik:GridViewDataColumn Header="Macchina"  HeaderTextAlignment="Center"
DataMemberBinding="{Binding MachineryNumber}" TextAlignment="Center" Width="60"/>
                        <telerik:GridViewDataColumn Header="Descrizione macchina"
DataMemberBinding="{Binding MachineryDescription}"  Width="350"/>
                        <telerik:GridViewDataColumn Header="Qta da fare"  HeaderTextAlignment="Center"
DataMemberBinding="{Binding QtaToDo}" TextAlignment="Center"  Width="70"/>
                        <telerik:GridViewDataColumn Header="Qta parziale"  HeaderTextAlignment="Center"
DataMemberBinding="{Binding QtaPartialDone}"  TextAlignment="Center" Width="80">
                        </telerik:GridViewDataColumn>
                        <telerik:GridViewDataColumn Header="Qta totale prodotta"  HeaderTextAlignment="Center"
DataMemberBinding="{Binding QtaDone}"  TextAlignment="Center" Width="120"/>
                        <telerik:GridViewDataColumn Header="Qta/h reali"  HeaderTextAlignment="Center"
DataMemberBinding="{Binding QtaDoneForHour}"  TextAlignment="Center" Width="70"/>
                        <telerik:GridViewDataColumn Header="Stato"  HeaderTextAlignment="Center"   
DataMemberBinding="{Binding MachineryStateDescription}"  TextAlignment="Center" Width="200">
                            <telerik:GridViewDataColumn.CellStyle>
                                <Style TargetType="telerik:GridViewCell">
                                    <Style.Triggers>
                                        <DataTrigger Binding="{Binding MachineryStateDescription}" Value="Controllo Produzione">
                                            <Setter Property="Background" Value="Blue" />
                                            <Setter Property="Foreground" Value="Yellow" />
                                        </DataTrigger>
                                        <DataTrigger Binding="{Binding MachineryStateDescription}" Value="In produzione">
                                            <Setter Property="Background" Value="LightGreen" />
                                            <Setter Property="Foreground" Value="Blue" />
                                        </DataTrigger>
                                        <DataTrigger Binding="{Binding MachineryStateDescription}" Value="Macchinario acceso">
                                            <Setter Property="Background" Value="Gray" />
                                            <Setter Property="Foreground" Value="White" />
                                        </DataTrigger>
                                        <DataTrigger Binding="{Binding MachineryStateDescription}" Value="Setup">
                                            <Setter Property="Background" Value="Brown" />
                                            <Setter Property="Foreground" Value="Yellow" />
                                        </DataTrigger>
                                        <DataTrigger Binding="{Binding MachineryStateDescription}" Value="Allarme">
                                            <Setter Property="Background" Value="Red" />
                                            <Setter Property="Foreground" Value="White" />
                                        </DataTrigger>

                                        <DataTrigger Binding="{Binding MachineryStateDescription}" Value="Allarme Linea">
                                            <Setter Property="Background" Value="Red" />
                                            <Setter Property="Foreground" Value="White" />
                                        </DataTrigger>
                                        <DataTrigger Binding="{Binding MachineryStateDescription}" Value="Allarme lubrificazione">
                                            <Setter Property="Background" Value="Red" />
                                            <Setter Property="Foreground" Value="White" />
                                        </DataTrigger>
                                        <DataTrigger Binding="{Binding MachineryStateDescription}" Value="Allarme stampo">
                                            <Setter Property="Background" Value="Red" />
                                            <Setter Property="Foreground" Value="White" />
                                        </DataTrigger>
                                        <DataTrigger Binding="{Binding MachineryStateDescription}" Value="Allarme aria">
                                            <Setter Property="Background" Value="Red" />
                                            <Setter Property="Foreground" Value="White" />
                                        </DataTrigger>
                                        <DataTrigger Binding="{Binding MachineryStateDescription}" Value="Allarme robot">
                                            <Setter Property="Background" Value="Red" />
                                            <Setter Property="Foreground" Value="White" />
                                        </DataTrigger>
                                        <DataTrigger Binding="{Binding MachineryStateDescription}" Value="Allarme termica di trasmissione">
                                            <Setter Property="Background" Value="Red" />
                                            <Setter Property="Foreground" Value="White" />
                                        </DataTrigger>

                                        <DataTrigger Binding="{Binding MachineryStateDescription}" Value="Allarme termico">
                                            <Setter Property="Background" Value="Red" />
                                            <Setter Property="Foreground" Value="White" />
                                        </DataTrigger>
                                        <DataTrigger Binding="{Binding MachineryStateDescription}" Value="Controllo pezzo">
                                            <Setter Property="Background" Value="Khaki" />
                                            <Setter Property="Foreground" Value="Black" />
                                        </DataTrigger>
                                        <DataTrigger Binding="{Binding MachineryStateDescription}" Value="Controllo passo F/C">
                                            <Setter Property="Background" Value="Khaki" />
                                            <Setter Property="Foreground" Value="Black" />
                                        </DataTrigger>
                                        <DataTrigger Binding="{Binding MachineryStateDescription}" Value="Controllo passo F/T">
                                            <Setter Property="Background" Value="Khaki" />
                                            <Setter Property="Foreground" Value="Black" />
                                        </DataTrigger>
                                        <DataTrigger Binding="{Binding MachineryStateDescription}" Value="Cancelli aperti">
                                            <Setter Property="Background" Value="Goldenrod" />
                                            <Setter Property="Foreground" Value="Red" />
                                        </DataTrigger>
                                        <DataTrigger Binding="{Binding MachineryStateDescription}" Value="Allarme fotocellule/barriere">
                                            <Setter Property="Background" Value="Goldenrod" />
                                            <Setter Property="Foreground" Value="Red" />
                                        </DataTrigger>
                                        <DataTrigger Binding="{Binding MachineryStateDescription}" Value="Fermo macchinario ingiustificato">
                                            <Setter Property="Background" Value="Black" />
                                            <Setter Property="Foreground" Value="Yellow" />
                                        </DataTrigger>
                                    </Style.Triggers>
                                </Style>
                            </telerik:GridViewDataColumn.CellStyle>
                        </telerik:GridViewDataColumn>
                        <telerik:GridViewDataColumn Header="Inizio"  HeaderTextAlignment="Center"   DataFormatString="{}{0:dddd   dd/MM/yyyy    HH:mm:ss}"
DataMemberBinding="{Binding TimeToStart}"  TextAlignment="Center" Width="220"/>
                        <telerik:GridViewDataColumn Header="Fine"  HeaderTextAlignment="Center"  DataFormatString="{}{0:dddd   dd/MM/yyyy    HH:mm:ss}"
DataMemberBinding="{Binding TimeToFinish}"  TextAlignment="Center" Width="220"/>
                        <telerik:GridViewDataColumn Header="Tempo"  HeaderTextAlignment="Center" DataFormatString="{}{0:dddd HH:mm:ss}" 
DataMemberBinding="{Binding TimePassed}"  TextAlignment="Center" Width="100"/>
                    </telerik:RadGridView.Columns>
                </telerik:RadGridView>

 

0
Pawel
Top achievements
Rank 1
answered on 18 Jan 2019, 06:10 PM

:) It is getting kind of boring if you have memory issues you should do what? open memory profiler. Did you? Nope :)

 

Since you have showed your code, i know where is your problem for 100% and i assure you that it is not telerik problem, the problem is that, that you dont know how to write code using wpf. To write proper application you need to follow MVVM rules. 

 

If you will profile your application you will see that memory is growing and growing, even if you will use datagrid unless you did it the same as with the telerik one. 

So read aboout mvvm and you problem will disappear, if it will not, then read again :). 

You can ping me on hangouts PawelGorszczakPL@gmail.com, if you will have more questions.

0
Gianfranco
Top achievements
Rank 1
answered on 18 Jan 2019, 08:15 PM

Thanks Pawel for your answer
In fact, in my life as a software developer, I realized only very few web applications with the MVVC pattern.
Stupidly I thought that for industrial automation applications they could be "heavy".

So I made this project with MVC rules.
Before getting to know WPF , realized many windows form applications always for industrial automation; whereas my services have to interact with the microprocessors of industrial plants in terms of a few thousandths of a second I have opted for a "shorter way".
Surely I was wrong.
You wrote me:
"it is getting kind of boring if you have memory issues you should do what? open memory profiler. Did you? Nope"

Well.
Testing my application in front of the industrial plant (for now) is impossible, as I can not slow down the production of a large industry.
I tried to simulate in my office, programming a microprocessor that would simulate the behavior of the industrial plant, but, as previously said, everything works perfectly; without "OuOfMemory".

In the coming weeks I will compare myself with my colleagues who are very prepared with MVVC.

I only hope that I have chosen well to build industrial applications with WPF. I would not go back to "simple" winform applications.

Concluding
Your answer was very interesting.
I will make due consideration with my colleagues.
I will keep you updated.
Thanks for your time

 

 

 

 

 

 

Tags
GridView
Asked by
Gianfranco
Top achievements
Rank 1
Answers by
Pawel
Top achievements
Rank 1
Martin Ivanov
Telerik team
Gianfranco
Top achievements
Rank 1
Share this question
or