WPF drawing/memory issue
WPF drawing/memory issue
WPF drawing/memory issue
WPF drawing/memory issue
WPF drawing/memory issue
WPF drawing/memory issue WPF drawing/memory issue WPF drawing/memory issue WPF drawing/memory issue WPF drawing/memory issue WPF drawing/memory issue WPF drawing/memory issue WPF drawing/memory issue
WPF drawing/memory issue WPF drawing/memory issue
WPF drawing/memory issue
Go Back  Xtreme Visual Basic Talk > > > WPF drawing/memory issue


Reply
 
Thread Tools Display Modes
  #1  
Old 05-08-2008, 05:03 PM
an5w3r's Avatar
an5w3r an5w3r is offline
Senior Contributor
 
Join Date: Jan 2004
Location: Romania
Posts: 1,342
Question WPF drawing/memory issue


Hello... I'm trying to do some heavy drawing in a WPF application using VB.NET 2008. The problem is the following:
1) the drawing takes a lot of memory - 100.000 lines will take 20-50 MB of RAM (I checked using Task Manager and also a dump of my program memory)
2) after I close (set to Nothing) my drawing class, the space doesn't get free into memory, it remains the same... if I press the drawing button 3 times, I get something like 2.5 * initial size of the picture, when I should normally get only the initial size, because I set to Nothing the other instances.
Some of my code for drawing is the following... please tell me if I'm dping something wrong:

Code:
Public Sub New() ... some init things dv = New DrawingVisual() dc = dv.RenderOpen() ' get the visual context ... do some heavy drawing using drawline method ' --- finish the drawing dc.Close() Dim di As New DrawingImage(dv.Drawing) di.Freeze() ' create an image from what we have drawn and attach it to the drawingCanvas Dim img As New System.Windows.Controls.Image() img.Name = "chisq" img.Source = di img.Margin = New System.Windows.Thickness(XBORD, MAXY, 0, 0) img.HorizontalAlignment = Windows.HorizontalAlignment.Left img.VerticalAlignment = VerticalAlignment.Top di = Nothing dc = Nothing dv = Nothing drawingCanvas.Children.Add(img) End Sub Private Sub drawLine(ByRef drawingCanvas As Canvas, ByVal x1 As Integer, ByVal y1 As Integer, ByVal x2 As Integer, ByVal y2 As Integer, ByVal color As System.Windows.Media.Brush, Optional ByVal isDotted As Boolean = False) Dim pen As New System.Windows.Media.Pen(color, 1) If isDotted Then pen.Thickness = 2 pen.DashStyle = DashStyles.Dot End If dc.DrawLine(pen, New System.Windows.Point(x1, y1), New System.Windows.Point(x2, y2)) End Sub

Any ideas or comments will be highly appreciated. Thank you.
Also if you need more code for understanding the problem please let me know.
__________________
Fully customizable and easy to use .NET WPF charting library http://www.SoftwareGFX.com
Reply With Quote
  #2  
Old 05-08-2008, 05:26 PM
MKoslof's Avatar
MKoslofWPF drawing/memory issue MKoslof is offline
Cum Grano Salis

Retired Moderator
* Guru *
 
Join Date: Jul 2002
Location: Baltimore, Maryland
Posts: 14,636
Default

The garbage collector of .Net runs on a seperate thread and you can't really guarantee when it will run and typically its best practice to let garbage collection do its job for you...however, there are a few things you should do:

1) Most memory intensive objects have a Dispose method or implement IDisposable, when you done with them call their Dispose method. For example, the majority of the graphic class objects have a dispose method. You should call the .Dispose() method whenever its available

2) Custom classes which will be resource intensive should implement IDisposable and override the Dispose method to properly dispose of the class.

3) Try to avoid objects getting to the LOH. This is a large topic and I don't want to get too granular, but there are different levels of garbage collection. Large objects or objects which remain alive for a long period of time (still referenced somewhere) are moved to the LOH (Large Object Heap) and the .Net Garbage collector doesn't scan or clean up these objects as often as smaller generations. Do your best to keep your object size at a minimum and keep your scope as narrow as possible, don't leave references open for long periods of time, for no good reason (typically you can avoid this).
__________________
"Artificial Intelligence is no match for natural stupidity." ~unknown
Reply With Quote
  #3  
Old 05-08-2008, 05:31 PM
an5w3r's Avatar
an5w3r an5w3r is offline
Senior Contributor
 
Join Date: Jan 2004
Location: Romania
Posts: 1,342
Default

Ok, let me see if I understood correctly:

1) Use .Dispose() rather than object=nothing, right?
2) I should write my own code for the Dispose() method of my specially created classes. What if I write the code in the finalize section of the class?
3) My object are referenced by using local variables in a button click event and draw the whole content on a canvas which is passed as a byref parameter. It shouldn't be referenced elsewhere.

P.S. Also can you explain me a little more, if you have the time and proper mood, of how the GC or LOH work?
__________________
Fully customizable and easy to use .NET WPF charting library http://www.SoftwareGFX.com

Last edited by an5w3r; 05-09-2008 at 02:32 AM. Reason: missspelling the shouldn't with should :)
Reply With Quote
  #4  
Old 05-08-2008, 06:09 PM
MKoslof's Avatar
MKoslofWPF drawing/memory issue MKoslof is offline
Cum Grano Salis

Retired Moderator
* Guru *
 
Join Date: Jul 2002
Location: Baltimore, Maryland
Posts: 14,636
Default

What can't you use ByVal, what purpose does byRef hold?

You basically have the gist of my initial advice, destructors are invoked automatically, and cannot be invoked explicitly. The GC will do this for you, and if you aren't writing unmanaged code you shouldn't need to even play with this.

I'm getting ready to get some dinner and Garbage Collection is a massive topic. However, I believe this MSDN article will help shed light for you and talks about some best practices as well:

http://msdn.microsoft.com/en-us/library/ms973837.aspx
__________________
"Artificial Intelligence is no match for natural stupidity." ~unknown
Reply With Quote
  #5  
Old 05-08-2008, 08:07 PM
AtmaWeapon's Avatar
AtmaWeaponWPF drawing/memory issue AtmaWeapon is offline
Fabulous Florist

Forum Leader
* Guru *
 
Join Date: Feb 2004
Location: Austin, TX
Posts: 9,500
Default

Task manager is a poor tool for checking memory usage.

That said, WPF is going to consume a bit more memory than standard Windows Forms drawing. WPF uses retained-mode graphics, which means you draw to a buffer which is then kept in memory so things don't have to be re-rendered as often. Windows Forms lets you draw but retains nothing. Retained-mode graphics is going to use more memory, and there's no way around it.

For the questions about disposal, you should always call Dispose on something when you're done with it. Implementing IDisposable on your classes should be done if any of its members have a Dispose or Close method, and you should fish around for information about implementing it properly (this looks like a good one, but here's the basic idea:

Declare a private method with this signature:
Code:
Private Sub Dispose(ByVal disposing As Boolean)
Now, your public Dispose() method should be just like this:
Code:
Sub Dispose()
    Dispose(true)
    GC.SuppressFinalize(Me)
End Sub
There's a reason for this, I promise I'll tell you after we get done with the code. Now, the Dispose you defined earlier (the private one) should look like this:
Code:
Sub Dispose(ByVal disposing As Boolean)
    If disposing Then
        ' Get rid of managed resources here
    End If
    
    ' Get rid of unmanaged resources here
End Sub
Let's discuss what's going on. There are two types of resources: managed and unmanaged. Managed resources are .NET objects, unmanaged objects are things like file handles. There are two ways your object can be disposed: a user can call Dispose, or the garbage collector can finalize your object. When the user calls Dispose, you know that your object is in a valid state and you can do final cleanup on all of your resources. When the GC calls finalizers, you have no idea if your managed resources have already been finalized by the GC; you should not touch managed resources in this case. That's why we have the public Dispose call our private one with disposing set to True; we're telling our private method that it's safe to touch managed resources. As an added bonus, we tell the GC that it doesn't have to call finalizers on this class since we've already cleaned up.

You probably have no unmanaged resources, but it's good to make this pattern a habit. If you implemented a finalizer, it would look like this:
Code:
Sub Finalize()
    Dispose(false)
End Sub
This tell our private Dispose that it is NOT safe to work with managed objects, and we'll only clean up unmanaged resources.

Do not implement a finalizer if you do not have unmanaged resources. Objects that have explicit finalizers take longer to allocate, require more memory, and take longer for the GC to collect. If all you have is managed resources and your class is collected, the managed resources your class held will become subject to collection and the GC will get them eventually. Finalizers are for unmanaged resources that the GC cannot collect. Finalizers on objects with no unmanaged resources do nothing but drain performance.

That drawing methodology looks a little iffy as well. I'm not as well-versed in WPF as I should be, but tomorrow when I've got my books at my fingertips I'm going to look over what you're doing. What's drawingCanvas? Do the lines have to be connected? If so, you might want to consider a polyline instead of drawing several lines. I also noticed your DrawLine function declares a new Pen each time and does not dispose of it; Pens are very expensive UI items and I am positive if you restructured your application to avoid creating many pens you'd see better numbers. Either cache the pen in a class-level variable or make it a parameter to DrawLine. Personally, I'd make the initial code create two pens: one dotted and one solid, then pass the appropriate pen to the DrawLine method as a parameter.
Reply With Quote
  #6  
Old 05-09-2008, 02:40 AM
an5w3r's Avatar
an5w3r an5w3r is offline
Senior Contributor
 
Join Date: Jan 2004
Location: Romania
Posts: 1,342
Default

drawingCanvas is a System.Windows.Controls.Canvas

I draw the whole content on a DrawingVisual object and then I convert it to a System.Windows.Controls.Image and attach it to drawingCanvas.Children collection -> is there a better methodology of drawing in WPF?
__________________
Fully customizable and easy to use .NET WPF charting library http://www.SoftwareGFX.com
Reply With Quote
  #7  
Old 05-09-2008, 04:08 AM
an5w3r's Avatar
an5w3r an5w3r is offline
Senior Contributor
 
Join Date: Jan 2004
Location: Romania
Posts: 1,342
Default

Ok AtmaWeapon... I did some tweaking, created a general Pen object + Point and now I draw the line just by modifying those objects and I can say the memory used is way lower... the only problem is that now it hangs on this line Dim di As New DrawingImage(dv.Drawing) for drawings with more than 10.000 line. For the ones with 100-3000 lines it works in an instant. What should I do? Did you get your hands on that WPF book?

Code:
' --- finish the drawing

        dc.Close()

        Dim di As New DrawingImage(dv.Drawing)
        di.Freeze()

        ' create an image from what we have drawn and attach it to the drawingCanvas
        Dim img As New System.Windows.Controls.Image()
        img.Name = "chisq"
        img.Source = di
        img.Margin = New System.Windows.Thickness(XBORD, MAXY, 0, 0)

        img.HorizontalAlignment = Windows.HorizontalAlignment.Left
        img.VerticalAlignment = VerticalAlignment.Top

        di = Nothing
        dc = Nothing
        dv = Nothing

        drawingCanvas.Children.Add(img)
__________________
Fully customizable and easy to use .NET WPF charting library http://www.SoftwareGFX.com
Reply With Quote
  #8  
Old 05-09-2008, 08:08 AM
MKoslof's Avatar
MKoslofWPF drawing/memory issue MKoslof is offline
Cum Grano Salis

Retired Moderator
* Guru *
 
Join Date: Jul 2002
Location: Baltimore, Maryland
Posts: 14,636
Default

Atma has given you a good sample iterating the points I mentioned but I want to stress DO NOT use destructors unless you have unmanaged code, using Dispose where appropriate and properly coding your application will take care of your memory issues most likely.

Regarding performance, DrawingImage derives from ImageSource. Now you are telling this Image source to use a Drawing object for its content. So if we think about this, the fact that you are using an Image object to render your drawing, this is the majority of your overhead.

You should be able to add your drawing directly via the AddVisualChild() method. I believe there are some properties such as GetVisualChild which you must override, I don't recall exactly but the documentation will guide you through this. And I would recommend a VisualCollection to render your drawing object, this should also help.
__________________
"Artificial Intelligence is no match for natural stupidity." ~unknown
Reply With Quote
  #9  
Old 05-09-2008, 09:41 AM
AtmaWeapon's Avatar
AtmaWeaponWPF drawing/memory issue AtmaWeapon is offline
Fabulous Florist

Forum Leader
* Guru *
 
Join Date: Feb 2004
Location: Austin, TX
Posts: 9,500
Default

It looks like AddVisualChild is protected on pretty much anything but Window. If the canvas isn't directly necessary, then I don't know that it matters, but if he wants control over layout it might be a problem. However, you are correct that he needs to use this, as my book is pointing it out pretty clearly.

The first thing I tried was to derive from Canvas so I could use those methods; this works but is unsatisfactory because you can't use the properties of the canvas (Top, Bottom, etc.) to put the drawing where you want it because those properties work with UIElements and DrawingVisual is not a UIElement.

Next, I tried deriving a new control from FrameworkElement, hosting the drawing in that, then hosting the control in the canvas. This worked better. You still have nasty performance on resizing the window, but it's only using a few megs of memory and it's not hanging.

... Or at least I thought this was a solution until I constrained my drawing to make sure that all 10,000 points were on-screen at once. Then I started to experience the program hang you describe. I tried using RenderTargetBitmap to see if the problem was putting the points on the screen, but it seems like the problem is rendering 10,000 points period. This seems odd to me, but I don't have any more time to spend on it right now.

I'm really thinking custom rendering will be the solution here. Retained-mode graphics may not perform well with thousands of elements onscreen.
__________________
.NET Resources
My FAQ threads | Tutor's Corner | Code Library
I would bet money 2/3 of .NET questions are already answered in one of these three places.

Last edited by AtmaWeapon; 05-09-2008 at 09:57 AM.
Reply With Quote
  #10  
Old 05-09-2008, 11:03 AM
MKoslof's Avatar
MKoslofWPF drawing/memory issue MKoslof is offline
Cum Grano Salis

Retired Moderator
* Guru *
 
Join Date: Jul 2002
Location: Baltimore, Maryland
Posts: 14,636
Default

Hmmmmm....

It has been some time since I've done anything like this even though the technology is new per say. I played in beta, did a project/vector stuff right around the time of the RTM release and since then, haven't been working with this at all (trapped in C# and VB.net integration with MOSS 2007 recently).

Everything you have found is valid, I wasn't terribly concrete I gave some abstract points or areas to go off of, because I didn't have a lot of time to try to create a code sample myself.

I too (if I have time) will see what I can come up with. But I also think, if you are going to have thousands of elements maybe a custom rendering is the best approach, like you, I find this odd, but I have no backing or historical data to say it shouldn't be this way, only logic would tell me (as it did you) this shouldn't be a problem
__________________
"Artificial Intelligence is no match for natural stupidity." ~unknown
Reply With Quote
  #11  
Old 05-09-2008, 12:29 PM
an5w3r's Avatar
an5w3r an5w3r is offline
Senior Contributor
 
Join Date: Jan 2004
Location: Romania
Posts: 1,342
Default

Quote:
Originally Posted by AtmaWeapon View Post
It looks like AddVisualChild is protected on pretty much anything but Window. If the canvas isn't directly necessary, then I don't know that it matters, but if he wants control over layout it might be a problem. However, you are correct that he needs to use this, as my book is pointing it out pretty clearly.

The first thing I tried was to derive from Canvas so I could use those methods; this works but is unsatisfactory because you can't use the properties of the canvas (Top, Bottom, etc.) to put the drawing where you want it because those properties work with UIElements and DrawingVisual is not a UIElement.

Next, I tried deriving a new control from FrameworkElement, hosting the drawing in that, then hosting the control in the canvas. This worked better. You still have nasty performance on resizing the window, but it's only using a few megs of memory and it's not hanging.

... Or at least I thought this was a solution until I constrained my drawing to make sure that all 10,000 points were on-screen at once. Then I started to experience the program hang you describe. I tried using RenderTargetBitmap to see if the problem was putting the points on the screen, but it seems like the problem is rendering 10,000 points period. This seems odd to me, but I don't have any more time to spend on it right now.

I'm really thinking custom rendering will be the solution here. Retained-mode graphics may not perform well with thousands of elements onscreen.
Thank you for the reply. I found a perfect example here, but my main problem is that I'm not drawing in the Window/Page that has the canvas. I have all the drawing calculations and methods in a public class and I draw on the canvas, just by passing as a reference the canvas control of the form I want to draw on. So basically I have access only to the Canvas as a control and I cannot override the VisualChildrenCount method, because that is related to the form's methods. What should I do?
__________________
Fully customizable and easy to use .NET WPF charting library http://www.SoftwareGFX.com
Reply With Quote
  #12  
Old 05-09-2008, 12:57 PM
AtmaWeapon's Avatar
AtmaWeaponWPF drawing/memory issue AtmaWeapon is offline
Fabulous Florist

Forum Leader
* Guru *
 
Join Date: Feb 2004
Location: Austin, TX
Posts: 9,500
Default

I'm not making the recommendation based on anything super concrete; WPF is new enough to me that I can't speak with authority. But the more I work with the Geometry objects the more it seems like they are meant for simple figures, not complicated ones.

The following is opinion, and I have no concrete data (trade secret or otherwise) to back it up:
It seems like you should treat segments of geometry objects like controls: anything over a few dozen and you're going to run into troubles. The delay doesn't seem to be adding Geometry objects to a group or adding segments to a figure, but when you actually render the geometry. My guess is WPF stores nothing but information until you actually ask for it to be rendered.

If this is true (and I believe it is) then custom rendering is going to be much faster. It seems like something in the geometry and drawing classes is adding a lot of overhead. I know the most naive approach to plotting points in Windows Forms performs acceptably for 10,000 data points, and I'd be astonished to find that the same approach in WPF deviates in a significant way.

As an aside, another disadvantage of the approaches I tried is you can't choose a pen on the fly, which seems to be a requirement. I was hoping to find a solution to the rendering problem first then work my way backwards, but it doesn't seem possible.

I've tried out some custom rendering but there's some weird behavior. The rendering loop between both my Windows Forms and WPF control take similar amounts of time to render. However, the WPF control hangs the application for several seconds after rendering is complete; I'm not really sure what causes this. Here's the source in case you can find something wrong with my logic:
Code:
Public Class DrawingControl
    Inherits FrameworkElement

    Dim _pointCount As Integer
    Dim _points() As Point

    Public Sub New()
        MyBase.New()
        _pointCount = 10
        GenerateData()
    End Sub

    Public Property PointCount() As Integer
        Get
            Return _pointCount
        End Get
        Set(ByVal value As Integer)
            _pointCount = value
            ' Not the best of ideas since this will take a while, but hey, example!
            GenerateData()
            Me.InvalidateVisual()
        End Set
    End Property

    Private Sub GenerateData()
        Dim rng As New Random()
        ReDim _points(Me.PointCount - 1)

        For i As Integer = 0 To _points.Length - 1
            _points(i) = New Point(rng.NextDouble(), rng.NextDouble())
        Next
    End Sub

    Protected Overrides Function MeasureOverride(ByVal availableSize As System.Windows.Size) As System.Windows.Size
        ' Normally, this function would look at its content and come up with a preferred
        ' size.  We're going to indicate that 200 x 200 is our preferred size, but we'll
        ' respect any smaller size as well.
        Dim preferredSize As New Size(200, 200)

        If availableSize.Width < preferredSize.Width OrElse _
           availableSize.Height < preferredSize.Height Then
            Return availableSize
        Else
            Return preferredSize
        End If
    End Function

    Protected Overrides Sub OnRender(ByVal drawingContext As System.Windows.Media.DrawingContext)
        Dim solid As New Pen(Brushes.Black, 2.0)

        Dim dashed As New Pen(Brushes.Blue, 2.0) With _
                                            {.DashStyle = New DashStyle(New Double() {2.0, 2.0}, 0)}
        Dim currentPen As Pen
        Dim lastPoint As New Point(0, 0)

        Dim sw As Stopwatch = Stopwatch.StartNew()
        ' Draw each point to render the control
        For i As Integer = 0 To _points.Length - 1
            ' Choose a pen
            currentPen = DirectCast(IIf(i Mod 2 = 0, solid, dashed), Pen)
            drawingContext.DrawLine(currentPen, TransformPoint(lastPoint), TransformPoint(_points(i)))
            lastPoint = _points(i)
        Next
        sw.Stop()
        Debug.WriteLine(String.Format("Took {0} to render {1}.", sw.ElapsedMilliseconds, _pointCount))
    End Sub

    Private Function TransformPoint(ByVal input As Point) As Point
        ' My data is in the range 0 - 1; I want to transform this into points in the range
        ' (0..width, 0..height).
        Dim transformed As New Point()
        transformed.X = input.X * Me.ActualWidth
        transformed.Y = input.Y * Me.ActualHeight

        Return transformed
    End Function

End Class
I'm really stumped here.
Reply With Quote
  #13  
Old 05-09-2008, 02:33 PM
an5w3r's Avatar
an5w3r an5w3r is offline
Senior Contributor
 
Join Date: Jan 2004
Location: Romania
Posts: 1,342
Default

I created a User Control (WPF) -> this creates both an xaml file for the interface and a xaml.vb file for adding code. I have one final problem. I did everything, added it in the main window as a custom Canvas, but inside the control I have a public method called draw that will do exactly what I want and it will call AddVisualChild(dv) and AddLogicalChild(dv) (dv is a DrawingVisual) once it is finished.

The XAML code in the main window for calling this custom control is:

Code:
<local:controlChiSQ Margin="212,238.98,0,0" x:Name="canvasChiSQ2" Height="232.943" VerticalAlignment="Top" HorizontalAlignment="Left" Width="487" />
Now I can refer in code to it as canvasChiSQ2. The problem is that I am not able to see its public method called draw and declared inside it -> that will draw the whole thing on it and then call the AddVisualChild.
Why doesn't it expose my public method?

P.S. If you ask yourself why I do this, the answer is because I have a program that does some calculations/simulations and after that I want to display a graph with current results and that's why I need to pass some parameters to my drawing routine.
__________________
Fully customizable and easy to use .NET WPF charting library http://www.SoftwareGFX.com

Last edited by an5w3r; 05-09-2008 at 02:54 PM.
Reply With Quote
  #14  
Old 05-10-2008, 09:10 AM
an5w3r's Avatar
an5w3r an5w3r is offline
Senior Contributor
 
Join Date: Jan 2004
Location: Romania
Posts: 1,342
Default

So boys... any idea?
__________________
Fully customizable and easy to use .NET WPF charting library http://www.SoftwareGFX.com
Reply With Quote
  #15  
Old 05-10-2008, 02:56 PM
MKoslof's Avatar
MKoslofWPF drawing/memory issue MKoslof is offline
Cum Grano Salis

Retired Moderator
* Guru *
 
Join Date: Jul 2002
Location: Baltimore, Maryland
Posts: 14,636
Default

Sorry my friend, I have done little to nothing with Xaml. It would be irresponsible of me to advise anything, cause I'm not experienced enough. I know you should have a partial class to go along with your object representation, but I would assume the public methods are exposed. Do you need to expose out or wrap this around a handler of some sort?

Maybe if Atma has done something with Xaml and custom user controls he can add his two cents...I can't really give more advice at this point in time I'm affraid if this is the new approach.
__________________
"Artificial Intelligence is no match for natural stupidity." ~unknown
Reply With Quote
  #16  
Old 05-11-2008, 03:55 AM
an5w3r's Avatar
an5w3r an5w3r is offline
Senior Contributor
 
Join Date: Jan 2004
Location: Romania
Posts: 1,342
Default

I have created my own custom control derived from Canvas and did the drawing stuff and for my surprise, for 10.000 lines it takes about 10-15 seconds to actually display it (just like it happened in your case Atma).

Code:
Public Class controlChiSQ
    Inherits System.Windows.Controls.Canvas

    Protected Overrides Sub OnRender(ByVal drawingContext As System.Windows.Media.DrawingContext)

        If Not spins Is Nothing Then
            drawGraph(drawingContext)
        End If

    End Sub

    Public Sub New()

        ' This call is required by the Windows Form Designer.
        InitializeComponent()

        ' Add any initialization after the InitializeComponent() call.

    End Sub

    Dim spins As ArrayList = Nothing
    Dim maxChiSQ As Double
    Dim dimensions As Rectangle
    Dim isSingle As Boolean
    Dim loading As LoadingWindow


    Public Sub passArguments(ByRef spins As ArrayList, ByVal maxChiSQ As Double, ByVal isSingle As Boolean, ByVal dimensions As Rectangle, _
                   ByRef loading As LoadingWindow)

        Me.spins = spins
        Me.dimensions = dimensions
        Me.maxChiSQ = maxChiSQ
        Me.isSingle = isSingle
        Me.loading = loading

        InvalidateVisual()

    End Sub


    Private Sub drawGraph(ByRef dc1 As DrawingContext)

        dc = dc1

   ' do stuff... draw lines, etc
    End Sub
Did you discover anything else meantime? The only way to draw superfast is just add Line objects to the canvas children property, but unfortunately for 1.000.000 lines it takes almost 1.3 GB of virtual memory and everything crashes.
So any thoughts?
__________________
Fully customizable and easy to use .NET WPF charting library http://www.SoftwareGFX.com
Reply With Quote
  #17  
Old 05-11-2008, 07:58 AM
MKoslof's Avatar
MKoslofWPF drawing/memory issue MKoslof is offline
Cum Grano Salis

Retired Moderator
* Guru *
 
Join Date: Jul 2002
Location: Baltimore, Maryland
Posts: 14,636
Default

My only other personal suggestion is use a profiler tool (I don't know if any are free, but you can get trials) and see where the majority of the time is being spent. If you find, and I suspect you will, its in the internals of the actual rendering, maybe kick this off async and use a prograss bar or please wait UI window that is on a seperate thread for a pleasant UI experience while the graph is rendering.

If you are hitting internal rendering issues,without completely re-engineering the application not sure what else you can do....again, maybe Atma has some suggestions.
__________________
"Artificial Intelligence is no match for natural stupidity." ~unknown
Reply With Quote
  #18  
Old 05-11-2008, 02:00 PM
AtmaWeapon's Avatar
AtmaWeaponWPF drawing/memory issue AtmaWeapon is offline
Fabulous Florist

Forum Leader
* Guru *
 
Join Date: Feb 2004
Location: Austin, TX
Posts: 9,500
Default

I have no advice.

(The below is an observation based on anecdotal evidence -- MS has not explicitly stated this opinion but I have extrapolated it from dozens of blog posts:)

The current WPF release is one meant to get WPF out into the industry and get people excited about its capabilities. There's quite a few things that cause performance problems (try animating FontSize; you'll see PresentationFontCache.exe's memory usage balloon up and your output window will fill with first-chance OutOfMemoryExceptions.) There's not a very good list of these things because MS is kind of finding them as people develop, and sometimes there's not a workaround because there's something they are doing wrong internally. Performance was not a concern of this release, and if you do intensive rendering speed comparisons between WPF and Windows Forms you'll find Windows Forms to be faster. Performance may be a concern of future WPF releases, but for now they are focusing on functionality.

If you really need to render several thousand points, I really think your best bet is to render offscreen to a bitmap then display the bitmap. I seem to recall trying this and it still had problems, so you may want to create a Windows Forms control that does the same and host that in your WPF application. I can't really offer more advice for two reasons: the first is I have no experience with drawing thousands of items in WPF and therefore no knowledge of best practices, and the second is if I did have the knowledge it would be directly related to the controls we develop at work and it would be against my contract to disclose most of the information.

Have you considered posting on the MSDN forums? I'm pretty sure they're open to the public, and the forums are visited by both Microsoft staff and MVPs. I'm sure there's an answer, but WPF is just too new for me to know the little tricks.

Last edited by AtmaWeapon; 05-11-2008 at 02:01 PM. Reason: stupid smiley parser
Reply With Quote
  #19  
Old 05-11-2008, 02:36 PM
an5w3r's Avatar
an5w3r an5w3r is offline
Senior Contributor
 
Join Date: Jan 2004
Location: Romania
Posts: 1,342
Default

Hello, I posted on MS forum, but no response, they suggested to use a profiler, dump the memory etc, etc but I didn't find anything that can truly help me achieve performance.
I was thinking also at writing a bmp on the fly pixel by pixel (just like I used to do in VB6 draw on a Picturebox using lines or pixels drawing), but I don't know the proper methods. Would you care to point me to 1-2 methods for that, if they are somewhere handy?
Nevertheless thank you a lot for your help and assistance in this problem.
__________________
Fully customizable and easy to use .NET WPF charting library http://www.SoftwareGFX.com
Reply With Quote
  #20  
Old 05-11-2008, 03:05 PM
MKoslof's Avatar
MKoslofWPF drawing/memory issue MKoslof is offline
Cum Grano Salis

Retired Moderator
* Guru *
 
Join Date: Jul 2002
Location: Baltimore, Maryland
Posts: 14,636
Default

Quote:
Hello, I posted on MS forum, but no response, they suggested to use a profiler, dump the memory etc, etc but I didn't find anything that can truly help me achieve performance.
Ug, a memory dump definately isn't going to be of much use to you. How did you profile this? I personally, don't know what MS/the forum told you, was talking about a tool such as ANTS or third party apps that give you reflection and the ability to performance-probe per event, per thread and exposes out private and internal calls...

But end of the day, I wouldn't waste too much time on this because you are going to find its WPF internals and nothing you are going to be able to change.

This is where I completely bail out of the conversation. I'm verse with graphics and I've done my share of charts, graphs and such, but Atma is definately going to be more of a guru regarding hard-core dynamic off line bitmap creation, this is where my pack up my geek tent and go home .

I will agree at this point, you should probably ditch WPF go for a custom Windows control. And given my own experiences with Microsoft, if you get into granular questions like this, they tend to become "surpisingly" unresponsive, I've got a lot of unanswered questions going back years now
__________________
"Artificial Intelligence is no match for natural stupidity." ~unknown

Last edited by MKoslof; 05-11-2008 at 03:13 PM.
Reply With Quote
Reply


Currently Active Users Viewing This Thread: 1 (0 members and 1 guests)
 
Thread Tools
Display Modes

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is Off
HTML code is Off

Forum Jump

Advertisement:





Free Publications
The ASP.NET 2.0 Anthology
101 Essential Tips, Tricks & Hacks - Free 156 Page Preview. Learn the most practical features and best approaches for ASP.NET.
subscribe
Programmers Heaven C# School Book -Free 338 Page eBook
The Programmers Heaven C# School book covers the .NET framework and the C# language.
subscribe
Build Your Own ASP.NET 3.5 Web Site Using C# & VB, 3rd Edition - Free 219 Page Preview!
This comprehensive step-by-step guide will help get your database-driven ASP.NET web site up and running in no time..
subscribe
WPF drawing/memory issue
WPF drawing/memory issue
WPF drawing/memory issue WPF drawing/memory issue
WPF drawing/memory issue
WPF drawing/memory issue
WPF drawing/memory issue WPF drawing/memory issue WPF drawing/memory issue WPF drawing/memory issue WPF drawing/memory issue WPF drawing/memory issue WPF drawing/memory issue
WPF drawing/memory issue
WPF drawing/memory issue
 
WPF drawing/memory issue
WPF drawing/memory issue
 
-->