How to make this better and faster?

Collapse
This topic is closed.
X
X
 
  • Time
  • Show
Clear All
new posts
  • ham-z

    How to make this better and faster?

    I have written the following Win app in VB.NET 2003 . The class is simply
    picture boxes that behave in a random order after they have been
    instantiated and added to a form. When I create 15 or more instances of my
    class, the whole program runs slowly in a way that I have to close the
    program. I have tried to create a new thread for each class, but that throws
    an exception , because a separated thread can't be added to a form from a
    child class.

    My code is this ( please tell me if there are better ways for doing it)
    coplile with :

    vbc [filename]
    /r:system.dll,sy stem.windows.fo rms.dll,system. drawing.dll,mic rosoft.visualba sic.dll
    /t:winexe /main:form1

    '----------------------------------- Start of CODE

    Imports System.Math
    imports Microsoft.Visua lBasic
    imports System.drawing
    imports system.windows. forms

    Public Class Form1
    Inherits System.Windows. Forms.Form

    #Region " Windows Form Designer generated code "

    Public Sub New()
    MyBase.New()

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

    'Add any initialization after the InitializeCompo nent() call

    End Sub

    'Form overrides dispose to clean up the component list.
    Protected Overloads Overrides Sub Dispose(ByVal disposing As Boolean)
    If disposing Then
    If Not (components Is Nothing) Then
    components.Disp ose()
    End If
    End If
    MyBase.Dispose( disposing)
    End Sub

    'Required by the Windows Form Designer
    Private components As System.Componen tModel.IContain er

    'NOTE: The following procedure is required by the Windows Form Designer
    'It can be modified using the Windows Form Designer.
    'Do not modify it using the code editor.
    <System.Diagnos tics.DebuggerSt epThrough()> Private Sub
    InitializeCompo nent()
    '
    'Form1
    '
    Me.AutoScaleBas eSize = New System.Drawing. Size(5, 13)
    Me.BackColor = System.Drawing. Color.White
    Me.ClientSize = New System.Drawing. Size(384, 266)
    Me.Name = "Form1"
    Me.Text = "Form1"

    End Sub

    #End Region

    Private Sub Form1_Click(ByV al sender As Object, ByVal e As
    System.EventArg s) Handles MyBase.Click
    CreateOBJ()
    End Sub


    Sub CreateOBJ()
    Dim myRec As Rec = New Rec(Me.CreateGr aphics, Me)
    End Sub
    End Class

    '--------------------------------------------------- Class Rec

    Public Class Rec

    Dim Gr As Graphics
    Dim X, Y As Integer
    Dim frm As Form
    WithEvents TIMER As New Timer
    Dim bmp As Bitmap
    Dim PB As PictureBox

    Public Sub New(ByVal g As Graphics, ByVal form As Form)
    X = Rnd() * 100
    Y = Rnd() * 200
    Gr = g
    Me.frm = form
    ini()
    justAddX = True
    justAddY = True
    End Sub

    ' We could use the graphics object here to draw on the form. But since
    GDI+
    ' lacks the ideal performance, we use picture boxes and add them to the
    ' spacified form instead of using the drawing object:

    Sub ini()
    TIMER.Interval = Rnd() * 10 + 1
    TIMER.Enabled = True
    PB = New PictureBox
    With PB
    .BackColor = Color.FromArgb( Rnd() * 150, Rnd() * 200, Rnd() *
    230)
    .Left = X
    .Top = Y
    .Height = 6
    .Width = 6
    End With
    frm.Controls.Ad d(PB)
    End Sub

    ' Use these two boolean to know when to add or substarct numbers
    ' the movement of this class object.
    Dim justAddX, justAddY As Boolean

    Private Sub TIMER_Tick(ByVa l sender As Object, ByVal e As
    System.EventArg s) Handles TIMER.Tick
    MoveMe()
    End Sub

    ' CuurentNum X , Y are the numbers added to the speed of X ,Y
    ' which creates a kind of change when the Rec hits the walls:

    Dim CurrentNumX As Integer = 1
    Dim CurrentNumY As Integer = 1

    Sub MoveMe()
    If X > (frm.Width - PB.Width) - 10 Then
    justAddX = False
    CurrentNumX = Rnd() * 50
    End If

    If Y > (frm.Height - PB.Height) - 30 Then
    justAddY = False
    CurrentNumY = Rnd() * 40
    End If

    If X < 0 Then
    justAddX = True
    CurrentNumX = Rnd() * 80
    End If

    If Y < 0 Then
    justAddY = True
    CurrentNumY = Rnd() * 30
    End If

    If justAddX Then
    X += CurrentNumX
    Else
    X -= CurrentNumX
    End If

    If justAddY Then
    Y += CurrentNumY
    Else
    Y -= CurrentNumY
    End If

    PB.Left = X
    PB.Top = Y
    End Sub

    End Class


    '------------------------------------------------------- End of
    CODE------------



  • Dennis

    #2
    RE: How to make this better and faster?

    You might want to check into the API routine BitBlt. It copies rectangle
    shapes from and to graphics objects. It's very, very fast. You could draw
    your images directly on the form using the Paint event.

    "ham-z" wrote:
    [color=blue]
    > I have written the following Win app in VB.NET 2003 . The class is simply
    > picture boxes that behave in a random order after they have been
    > instantiated and added to a form. When I create 15 or more instances of my
    > class, the whole program runs slowly in a way that I have to close the
    > program. I have tried to create a new thread for each class, but that throws
    > an exception , because a separated thread can't be added to a form from a
    > child class.
    >
    > My code is this ( please tell me if there are better ways for doing it)
    > coplile with :
    >
    > vbc [filename]
    > /r:system.dll,sy stem.windows.fo rms.dll,system. drawing.dll,mic rosoft.visualba sic.dll
    > /t:winexe /main:form1
    >
    > '----------------------------------- Start of CODE
    >
    > Imports System.Math
    > imports Microsoft.Visua lBasic
    > imports System.drawing
    > imports system.windows. forms
    >
    > Public Class Form1
    > Inherits System.Windows. Forms.Form
    >
    > #Region " Windows Form Designer generated code "
    >
    > Public Sub New()
    > MyBase.New()
    >
    > 'This call is required by the Windows Form Designer.
    > InitializeCompo nent()
    >
    > 'Add any initialization after the InitializeCompo nent() call
    >
    > End Sub
    >
    > 'Form overrides dispose to clean up the component list.
    > Protected Overloads Overrides Sub Dispose(ByVal disposing As Boolean)
    > If disposing Then
    > If Not (components Is Nothing) Then
    > components.Disp ose()
    > End If
    > End If
    > MyBase.Dispose( disposing)
    > End Sub
    >
    > 'Required by the Windows Form Designer
    > Private components As System.Componen tModel.IContain er
    >
    > 'NOTE: The following procedure is required by the Windows Form Designer
    > 'It can be modified using the Windows Form Designer.
    > 'Do not modify it using the code editor.
    > <System.Diagnos tics.DebuggerSt epThrough()> Private Sub
    > InitializeCompo nent()
    > '
    > 'Form1
    > '
    > Me.AutoScaleBas eSize = New System.Drawing. Size(5, 13)
    > Me.BackColor = System.Drawing. Color.White
    > Me.ClientSize = New System.Drawing. Size(384, 266)
    > Me.Name = "Form1"
    > Me.Text = "Form1"
    >
    > End Sub
    >
    > #End Region
    >
    > Private Sub Form1_Click(ByV al sender As Object, ByVal e As
    > System.EventArg s) Handles MyBase.Click
    > CreateOBJ()
    > End Sub
    >
    >
    > Sub CreateOBJ()
    > Dim myRec As Rec = New Rec(Me.CreateGr aphics, Me)
    > End Sub
    > End Class
    >
    > '--------------------------------------------------- Class Rec
    >
    > Public Class Rec
    >
    > Dim Gr As Graphics
    > Dim X, Y As Integer
    > Dim frm As Form
    > WithEvents TIMER As New Timer
    > Dim bmp As Bitmap
    > Dim PB As PictureBox
    >
    > Public Sub New(ByVal g As Graphics, ByVal form As Form)
    > X = Rnd() * 100
    > Y = Rnd() * 200
    > Gr = g
    > Me.frm = form
    > ini()
    > justAddX = True
    > justAddY = True
    > End Sub
    >
    > ' We could use the graphics object here to draw on the form. But since
    > GDI+
    > ' lacks the ideal performance, we use picture boxes and add them to the
    > ' spacified form instead of using the drawing object:
    >
    > Sub ini()
    > TIMER.Interval = Rnd() * 10 + 1
    > TIMER.Enabled = True
    > PB = New PictureBox
    > With PB
    > .BackColor = Color.FromArgb( Rnd() * 150, Rnd() * 200, Rnd() *
    > 230)
    > .Left = X
    > .Top = Y
    > .Height = 6
    > .Width = 6
    > End With
    > frm.Controls.Ad d(PB)
    > End Sub
    >
    > ' Use these two boolean to know when to add or substarct numbers
    > ' the movement of this class object.
    > Dim justAddX, justAddY As Boolean
    >
    > Private Sub TIMER_Tick(ByVa l sender As Object, ByVal e As
    > System.EventArg s) Handles TIMER.Tick
    > MoveMe()
    > End Sub
    >
    > ' CuurentNum X , Y are the numbers added to the speed of X ,Y
    > ' which creates a kind of change when the Rec hits the walls:
    >
    > Dim CurrentNumX As Integer = 1
    > Dim CurrentNumY As Integer = 1
    >
    > Sub MoveMe()
    > If X > (frm.Width - PB.Width) - 10 Then
    > justAddX = False
    > CurrentNumX = Rnd() * 50
    > End If
    >
    > If Y > (frm.Height - PB.Height) - 30 Then
    > justAddY = False
    > CurrentNumY = Rnd() * 40
    > End If
    >
    > If X < 0 Then
    > justAddX = True
    > CurrentNumX = Rnd() * 80
    > End If
    >
    > If Y < 0 Then
    > justAddY = True
    > CurrentNumY = Rnd() * 30
    > End If
    >
    > If justAddX Then
    > X += CurrentNumX
    > Else
    > X -= CurrentNumX
    > End If
    >
    > If justAddY Then
    > Y += CurrentNumY
    > Else
    > Y -= CurrentNumY
    > End If
    >
    > PB.Left = X
    > PB.Top = Y
    > End Sub
    >
    > End Class
    >
    >
    > '------------------------------------------------------- End of
    > CODE------------
    >
    >
    >
    >[/color]

    Comment

    • Cor Ligthert

      #3
      Re: How to make this better and faster?

      Ham,

      Nice crossposting, however the in my opinion most right newsgroup for this
      question is not in it.

      microsoft.publi c.dotnet.framew ork.drawing

      I saw your problem, however I think because the fact that the most is
      graphics you can place it the best in that newsgroup.

      No problem at all that crossposting by the way.

      Cor

      "ham-z" <hamz-3e@/**/yahoo.com>.[color=blue]
      >I have written the following Win app in VB.NET 2003 . The class is simply
      > picture boxes that behave in a random order after they have been
      > instantiated and added to a form. When I create 15 or more instances of my
      > class, the whole program runs slowly in a way that I have to close the
      > program. I have tried to create a new thread for each class, but that
      > throws
      > an exception , because a separated thread can't be added to a form from a
      > child class.
      >
      > My code is this ( please tell me if there are better ways for doing it)
      > coplile with :
      >
      > vbc [filename]
      > /r:system.dll,sy stem.windows.fo rms.dll,system. drawing.dll,mic rosoft.visualba sic.dll
      > /t:winexe /main:form1
      >
      > '----------------------------------- Start of CODE
      >
      > Imports System.Math
      > imports Microsoft.Visua lBasic
      > imports System.drawing
      > imports system.windows. forms
      >
      > Public Class Form1
      > Inherits System.Windows. Forms.Form
      >
      > #Region " Windows Form Designer generated code "
      >
      > Public Sub New()
      > MyBase.New()
      >
      > 'This call is required by the Windows Form Designer.
      > InitializeCompo nent()
      >
      > 'Add any initialization after the InitializeCompo nent() call
      >
      > End Sub
      >
      > 'Form overrides dispose to clean up the component list.
      > Protected Overloads Overrides Sub Dispose(ByVal disposing As Boolean)
      > If disposing Then
      > If Not (components Is Nothing) Then
      > components.Disp ose()
      > End If
      > End If
      > MyBase.Dispose( disposing)
      > End Sub
      >
      > 'Required by the Windows Form Designer
      > Private components As System.Componen tModel.IContain er
      >
      > 'NOTE: The following procedure is required by the Windows Form Designer
      > 'It can be modified using the Windows Form Designer.
      > 'Do not modify it using the code editor.
      > <System.Diagnos tics.DebuggerSt epThrough()> Private Sub
      > InitializeCompo nent()
      > '
      > 'Form1
      > '
      > Me.AutoScaleBas eSize = New System.Drawing. Size(5, 13)
      > Me.BackColor = System.Drawing. Color.White
      > Me.ClientSize = New System.Drawing. Size(384, 266)
      > Me.Name = "Form1"
      > Me.Text = "Form1"
      >
      > End Sub
      >
      > #End Region
      >
      > Private Sub Form1_Click(ByV al sender As Object, ByVal e As
      > System.EventArg s) Handles MyBase.Click
      > CreateOBJ()
      > End Sub
      >
      >
      > Sub CreateOBJ()
      > Dim myRec As Rec = New Rec(Me.CreateGr aphics, Me)
      > End Sub
      > End Class
      >
      > '--------------------------------------------------- Class Rec
      >
      > Public Class Rec
      >
      > Dim Gr As Graphics
      > Dim X, Y As Integer
      > Dim frm As Form
      > WithEvents TIMER As New Timer
      > Dim bmp As Bitmap
      > Dim PB As PictureBox
      >
      > Public Sub New(ByVal g As Graphics, ByVal form As Form)
      > X = Rnd() * 100
      > Y = Rnd() * 200
      > Gr = g
      > Me.frm = form
      > ini()
      > justAddX = True
      > justAddY = True
      > End Sub
      >
      > ' We could use the graphics object here to draw on the form. But since
      > GDI+
      > ' lacks the ideal performance, we use picture boxes and add them to the
      > ' spacified form instead of using the drawing object:
      >
      > Sub ini()
      > TIMER.Interval = Rnd() * 10 + 1
      > TIMER.Enabled = True
      > PB = New PictureBox
      > With PB
      > .BackColor = Color.FromArgb( Rnd() * 150, Rnd() * 200, Rnd() *
      > 230)
      > .Left = X
      > .Top = Y
      > .Height = 6
      > .Width = 6
      > End With
      > frm.Controls.Ad d(PB)
      > End Sub
      >
      > ' Use these two boolean to know when to add or substarct numbers
      > ' the movement of this class object.
      > Dim justAddX, justAddY As Boolean
      >
      > Private Sub TIMER_Tick(ByVa l sender As Object, ByVal e As
      > System.EventArg s) Handles TIMER.Tick
      > MoveMe()
      > End Sub
      >
      > ' CuurentNum X , Y are the numbers added to the speed of X ,Y
      > ' which creates a kind of change when the Rec hits the walls:
      >
      > Dim CurrentNumX As Integer = 1
      > Dim CurrentNumY As Integer = 1
      >
      > Sub MoveMe()
      > If X > (frm.Width - PB.Width) - 10 Then
      > justAddX = False
      > CurrentNumX = Rnd() * 50
      > End If
      >
      > If Y > (frm.Height - PB.Height) - 30 Then
      > justAddY = False
      > CurrentNumY = Rnd() * 40
      > End If
      >
      > If X < 0 Then
      > justAddX = True
      > CurrentNumX = Rnd() * 80
      > End If
      >
      > If Y < 0 Then
      > justAddY = True
      > CurrentNumY = Rnd() * 30
      > End If
      >
      > If justAddX Then
      > X += CurrentNumX
      > Else
      > X -= CurrentNumX
      > End If
      >
      > If justAddY Then
      > Y += CurrentNumY
      > Else
      > Y -= CurrentNumY
      > End If
      >
      > PB.Left = X
      > PB.Top = Y
      > End Sub
      >
      > End Class
      >
      >
      > '------------------------------------------------------- End of
      > CODE------------
      >
      >
      >[/color]


      Comment

      • Herfried K. Wagner [MVP]

        #4
        Re: How to make this better and faster?

        "Dennis" <Dennis@discuss ions.microsoft. com> schrieb:[color=blue]
        > You might want to check into the API routine BitBlt. It copies rectangle
        > shapes from and to graphics objects. It's very, very fast. You could
        > draw
        > your images directly on the form using the Paint event.[/color]

        I doubt that this will be much faster than 'Graphics.DrawI mage[Unscaled]'.

        --
        M S Herfried K. Wagner
        M V P <URL:http://dotnet.mvps.org/>
        V B <URL:http://dotnet.mvps.org/dotnet/faqs/>

        Comment

        • Nick Malik

          #5
          Re: How to make this better and faster?

          OK, so you have a form that **VERY QUICKLY** moves boxes at random around
          the screen.
          Realize that your timer ticks are happening so quickly that the system will
          be queueing events and colliding with itself on each form, and that will
          only get worse with additional forms.

          I'm not sure what you are trying to prove with this graphics exercise. If
          you want to see how fast graphics can move, than causing a timer conflict is
          probably not the best way to go about it. If you are trying to see how the
          OS handles PAINT events, then you may want to have a single form and stress
          it, rather than using a timer at all.

          Also, your timer is declared in the object, not in the form. The means that
          every new object you create will create a new timer. This may be a trivial
          point, but I'd recommend that you move the timer to the form.

          More importantly, to make your window perform, I'd suggest you change a
          single line.
          from: TIMER.Interval = Rnd() * 10 + 1
          from: TIMER.Interval = Rnd() * 10 + 100

          That will give you 10 Paint events per second per form, which is still
          plenty fast enough but is less likely to cause a pile-up.
          --
          --- Nick Malik [MSFT]
          MCSD, CFPS, Certified Scrummaster


          Disclaimer: Opinions expressed in this forum are my own, and not
          representative of my employer.
          I do not answer questions on behalf of my employer. I'm just a
          programmer helping programmers.

          "ham-z" <hamz-3e@/**/yahoo.com> wrote in message
          news:Ot3Btv15EH A.2608@TK2MSFTN GP10.phx.gbl...[color=blue]
          > I have written the following Win app in VB.NET 2003 . The class is simply
          > picture boxes that behave in a random order after they have been
          > instantiated and added to a form. When I create 15 or more instances of my
          > class, the whole program runs slowly in a way that I have to close the
          > program. I have tried to create a new thread for each class, but that[/color]
          throws[color=blue]
          > an exception , because a separated thread can't be added to a form from a
          > child class.
          >
          > My code is this ( please tell me if there are better ways for doing it)
          > coplile with :
          >
          > vbc [filename]
          >[/color]
          /r:system.dll,sy stem.windows.fo rms.dll,system. drawing.dll,mic rosoft.visualba
          sic.dll[color=blue]
          > /t:winexe /main:form1
          >
          > '----------------------------------- Start of CODE
          >
          > Imports System.Math
          > imports Microsoft.Visua lBasic
          > imports System.drawing
          > imports system.windows. forms
          >
          > Public Class Form1
          > Inherits System.Windows. Forms.Form
          >
          > #Region " Windows Form Designer generated code "
          >
          > Public Sub New()
          > MyBase.New()
          >
          > 'This call is required by the Windows Form Designer.
          > InitializeCompo nent()
          >
          > 'Add any initialization after the InitializeCompo nent() call
          >
          > End Sub
          >
          > 'Form overrides dispose to clean up the component list.
          > Protected Overloads Overrides Sub Dispose(ByVal disposing As Boolean)
          > If disposing Then
          > If Not (components Is Nothing) Then
          > components.Disp ose()
          > End If
          > End If
          > MyBase.Dispose( disposing)
          > End Sub
          >
          > 'Required by the Windows Form Designer
          > Private components As System.Componen tModel.IContain er
          >
          > 'NOTE: The following procedure is required by the Windows Form[/color]
          Designer[color=blue]
          > 'It can be modified using the Windows Form Designer.
          > 'Do not modify it using the code editor.
          > <System.Diagnos tics.DebuggerSt epThrough()> Private Sub
          > InitializeCompo nent()
          > '
          > 'Form1
          > '
          > Me.AutoScaleBas eSize = New System.Drawing. Size(5, 13)
          > Me.BackColor = System.Drawing. Color.White
          > Me.ClientSize = New System.Drawing. Size(384, 266)
          > Me.Name = "Form1"
          > Me.Text = "Form1"
          >
          > End Sub
          >
          > #End Region
          >
          > Private Sub Form1_Click(ByV al sender As Object, ByVal e As
          > System.EventArg s) Handles MyBase.Click
          > CreateOBJ()
          > End Sub
          >
          >
          > Sub CreateOBJ()
          > Dim myRec As Rec = New Rec(Me.CreateGr aphics, Me)
          > End Sub
          > End Class
          >
          > '--------------------------------------------------- Class Rec
          >
          > Public Class Rec
          >
          > Dim Gr As Graphics
          > Dim X, Y As Integer
          > Dim frm As Form
          > WithEvents TIMER As New Timer
          > Dim bmp As Bitmap
          > Dim PB As PictureBox
          >
          > Public Sub New(ByVal g As Graphics, ByVal form As Form)
          > X = Rnd() * 100
          > Y = Rnd() * 200
          > Gr = g
          > Me.frm = form
          > ini()
          > justAddX = True
          > justAddY = True
          > End Sub
          >
          > ' We could use the graphics object here to draw on the form. But since
          > GDI+
          > ' lacks the ideal performance, we use picture boxes and add them to[/color]
          the[color=blue]
          > ' spacified form instead of using the drawing object:
          >
          > Sub ini()
          > TIMER.Interval = Rnd() * 10 + 1
          > TIMER.Enabled = True
          > PB = New PictureBox
          > With PB
          > .BackColor = Color.FromArgb( Rnd() * 150, Rnd() * 200, Rnd() *
          > 230)
          > .Left = X
          > .Top = Y
          > .Height = 6
          > .Width = 6
          > End With
          > frm.Controls.Ad d(PB)
          > End Sub
          >
          > ' Use these two boolean to know when to add or substarct numbers
          > ' the movement of this class object.
          > Dim justAddX, justAddY As Boolean
          >
          > Private Sub TIMER_Tick(ByVa l sender As Object, ByVal e As
          > System.EventArg s) Handles TIMER.Tick
          > MoveMe()
          > End Sub
          >
          > ' CuurentNum X , Y are the numbers added to the speed of X ,Y
          > ' which creates a kind of change when the Rec hits the walls:
          >
          > Dim CurrentNumX As Integer = 1
          > Dim CurrentNumY As Integer = 1
          >
          > Sub MoveMe()
          > If X > (frm.Width - PB.Width) - 10 Then
          > justAddX = False
          > CurrentNumX = Rnd() * 50
          > End If
          >
          > If Y > (frm.Height - PB.Height) - 30 Then
          > justAddY = False
          > CurrentNumY = Rnd() * 40
          > End If
          >
          > If X < 0 Then
          > justAddX = True
          > CurrentNumX = Rnd() * 80
          > End If
          >
          > If Y < 0 Then
          > justAddY = True
          > CurrentNumY = Rnd() * 30
          > End If
          >
          > If justAddX Then
          > X += CurrentNumX
          > Else
          > X -= CurrentNumX
          > End If
          >
          > If justAddY Then
          > Y += CurrentNumY
          > Else
          > Y -= CurrentNumY
          > End If
          >
          > PB.Left = X
          > PB.Top = Y
          > End Sub
          >
          > End Class
          >
          >
          > '------------------------------------------------------- End of
          > CODE------------
          >
          >
          >[/color]


          Comment

          • Rulin Hong

            #6
            RE: How to make this better and faster?

            It's OK on my machine even when I created 200 instances of rec. My machine
            is: Intel(R) Pentium (R) 4 CPU 2.40GHZ | AT/AT COMPATIBLE | 1G RAM

            Comment

            • Frank Hileman

              #7
              Re: How to make this better and faster?

              What you need is a single control, not multiple PictureBoxes, that you draw
              on. Create a custom control class, double buffered, that draws everything
              you need. Multi-threading is unnecessary and will only cause tragedy.

              To see the maximum performance you can get from GDI+ try the Scalability
              sample source in the VG.net Lite installation. It uses an optimized run-time
              engine layered on GDI+. You can create and time 1K-100K rectangles. The
              timing framework can be reused to benchmark other implementations .

              Regards,
              Frank Hileman

              check out VG.net: http://www.vgdotnet.com
              Animated vector graphics system
              Integrated Visual Studio .NET graphics editor


              "ham-z" <hamz-3e@/**/yahoo.com> wrote in message
              news:Ot3Btv15EH A.2608@TK2MSFTN GP10.phx.gbl...[color=blue]
              >I have written the following Win app in VB.NET 2003 . The class is simply
              > picture boxes that behave in a random order after they have been
              > instantiated and added to a form. When I create 15 or more instances of my
              > class, the whole program runs slowly in a way that I have to close the
              > program. I have tried to create a new thread for each class, but that
              > throws
              > an exception , because a separated thread can't be added to a form from a
              > child class.
              >
              > My code is this ( please tell me if there are better ways for doing it)
              > coplile with :
              >
              > vbc [filename]
              > /r:system.dll,sy stem.windows.fo rms.dll,system. drawing.dll,mic rosoft.visualba sic.dll
              > /t:winexe /main:form1
              >
              > '----------------------------------- Start of CODE
              >
              > Imports System.Math
              > imports Microsoft.Visua lBasic
              > imports System.drawing
              > imports system.windows. forms
              >
              > Public Class Form1
              > Inherits System.Windows. Forms.Form
              >
              > #Region " Windows Form Designer generated code "
              >
              > Public Sub New()
              > MyBase.New()
              >
              > 'This call is required by the Windows Form Designer.
              > InitializeCompo nent()
              >
              > 'Add any initialization after the InitializeCompo nent() call
              >
              > End Sub
              >
              > 'Form overrides dispose to clean up the component list.
              > Protected Overloads Overrides Sub Dispose(ByVal disposing As Boolean)
              > If disposing Then
              > If Not (components Is Nothing) Then
              > components.Disp ose()
              > End If
              > End If
              > MyBase.Dispose( disposing)
              > End Sub
              >
              > 'Required by the Windows Form Designer
              > Private components As System.Componen tModel.IContain er
              >
              > 'NOTE: The following procedure is required by the Windows Form Designer
              > 'It can be modified using the Windows Form Designer.
              > 'Do not modify it using the code editor.
              > <System.Diagnos tics.DebuggerSt epThrough()> Private Sub
              > InitializeCompo nent()
              > '
              > 'Form1
              > '
              > Me.AutoScaleBas eSize = New System.Drawing. Size(5, 13)
              > Me.BackColor = System.Drawing. Color.White
              > Me.ClientSize = New System.Drawing. Size(384, 266)
              > Me.Name = "Form1"
              > Me.Text = "Form1"
              >
              > End Sub
              >
              > #End Region
              >
              > Private Sub Form1_Click(ByV al sender As Object, ByVal e As
              > System.EventArg s) Handles MyBase.Click
              > CreateOBJ()
              > End Sub
              >
              >
              > Sub CreateOBJ()
              > Dim myRec As Rec = New Rec(Me.CreateGr aphics, Me)
              > End Sub
              > End Class
              >
              > '--------------------------------------------------- Class Rec
              >
              > Public Class Rec
              >
              > Dim Gr As Graphics
              > Dim X, Y As Integer
              > Dim frm As Form
              > WithEvents TIMER As New Timer
              > Dim bmp As Bitmap
              > Dim PB As PictureBox
              >
              > Public Sub New(ByVal g As Graphics, ByVal form As Form)
              > X = Rnd() * 100
              > Y = Rnd() * 200
              > Gr = g
              > Me.frm = form
              > ini()
              > justAddX = True
              > justAddY = True
              > End Sub
              >
              > ' We could use the graphics object here to draw on the form. But since
              > GDI+
              > ' lacks the ideal performance, we use picture boxes and add them to the
              > ' spacified form instead of using the drawing object:
              >
              > Sub ini()
              > TIMER.Interval = Rnd() * 10 + 1
              > TIMER.Enabled = True
              > PB = New PictureBox
              > With PB
              > .BackColor = Color.FromArgb( Rnd() * 150, Rnd() * 200, Rnd() *
              > 230)
              > .Left = X
              > .Top = Y
              > .Height = 6
              > .Width = 6
              > End With
              > frm.Controls.Ad d(PB)
              > End Sub
              >
              > ' Use these two boolean to know when to add or substarct numbers
              > ' the movement of this class object.
              > Dim justAddX, justAddY As Boolean
              >
              > Private Sub TIMER_Tick(ByVa l sender As Object, ByVal e As
              > System.EventArg s) Handles TIMER.Tick
              > MoveMe()
              > End Sub
              >
              > ' CuurentNum X , Y are the numbers added to the speed of X ,Y
              > ' which creates a kind of change when the Rec hits the walls:
              >
              > Dim CurrentNumX As Integer = 1
              > Dim CurrentNumY As Integer = 1
              >
              > Sub MoveMe()
              > If X > (frm.Width - PB.Width) - 10 Then
              > justAddX = False
              > CurrentNumX = Rnd() * 50
              > End If
              >
              > If Y > (frm.Height - PB.Height) - 30 Then
              > justAddY = False
              > CurrentNumY = Rnd() * 40
              > End If
              >
              > If X < 0 Then
              > justAddX = True
              > CurrentNumX = Rnd() * 80
              > End If
              >
              > If Y < 0 Then
              > justAddY = True
              > CurrentNumY = Rnd() * 30
              > End If
              >
              > If justAddX Then
              > X += CurrentNumX
              > Else
              > X -= CurrentNumX
              > End If
              >
              > If justAddY Then
              > Y += CurrentNumY
              > Else
              > Y -= CurrentNumY
              > End If
              >
              > PB.Left = X
              > PB.Top = Y
              > End Sub
              >
              > End Class
              >
              >
              > '------------------------------------------------------- End of
              > CODE------------
              >
              >
              >[/color]


              Comment

              • ham-z

                #8
                Re: How to make this better and faster?

                Nick Malik [MSFT] wrote:[color=blue]
                > OK, so you have a form that **VERY QUICKLY** moves boxes at random around
                > the screen.
                > Realize that your timer ticks are happening so quickly that the system
                > will
                > be queueing events and colliding with itself on each form, and that will
                > only get worse with additional forms.[/color]

                Nice hint, but my PB object is responsible for it's own movement. It should
                have a built-in timer in order to move

                [color=blue]
                > I'm not sure what you are trying to prove with this graphics exercise.[/color]

                creating sth alive...look at this if you have MSDN 2003 installed:
                ms-help://MS.MSDNQTR.2003 APR.1033/dndllpro/html/msdn_frogfly1.h tm

                [color=blue]
                > Also, your timer is declared in the object, not in the form. The means
                > that
                > every new object you create will create a new timer. This may be a
                > trivial
                > point, but I'd recommend that you move the timer to the form.[/color]

                How? each object is responsible for its own movement....
                [color=blue]
                > More importantly, to make your window perform, I'd suggest you change a
                > single line.
                > from: TIMER.Interval = Rnd() * 10 + 1
                > from: TIMER.Interval = Rnd() * 10 + 100
                >
                > That will give you 10 Paint events per second per form, which is still
                > plenty fast enough but is less likely to cause a pile-up.[/color]

                Nice suggestion.
                Thanks anyway for help.





                Comment

                • ham-z

                  #9
                  Re: How to make this better and faster?

                  You got plenty of RAM.... mine is only 256 MB...though I can't figure out
                  what 1 GB RAM might do for this ( almost no relation) comparing with
                  256.....
                  "Rulin Hong" <RulinHong@disc ussions.microso ft.com> wrote in message
                  news:DC5D3BAD-0BD3-4255-8B5B-3EFB8175F4CD@mi crosoft.com...[color=blue]
                  > It's OK on my machine even when I created 200 instances of rec. My machine
                  > is: Intel(R) Pentium (R) 4 CPU 2.40GHZ | AT/AT COMPATIBLE | 1G RAM
                  >[/color]


                  Comment

                  • Frank Hileman

                    #10
                    Re: How to make this better and faster?

                    I looked at the MSDN reference. This is a good example of all the problems
                    you can have by using mutiple threads when they are not needed. It is a poor
                    article. The author believes mutiple threads are needed to update internal
                    state, even though the output is serialized to a single thread -- he is
                    perpetuating common misunderstandin gs.

                    In a simulation of multiple actors, the simplest single threaded approach is
                    to loop through all the actors when a Windows.Forms.T imer fires, updating
                    their internal state, then force a paint event to occur (invalidate modified
                    areas). The paint cannot occur faster than the timer in any circumstance, so
                    intermediate state changes are wasteful. If you need the state changes to be
                    dependent on the passage of time, you can use the Win32 high performance
                    timer to accurately determine elapsed time from the beginning of the
                    simulation, QueryPerformanc eCounter (a wrapper class is in the sample I
                    mentioned).

                    In the unlikely event the number of actors is so large that updating
                    internal state causes the UI to become unresponsive, you can process a
                    fixed, smaller number of actors on each timer tick, incrementing a processed
                    actor counter, avoiding invalidation of the control until all have been
                    processed. This is a second technique for avoiding multi-threading when it
                    is not needed, while maintaining a responsive UI. If you use this approach,
                    you should determine elapsed time, for the purpose of state changes, at the
                    first tick after a complete update, so that all actors work with a
                    consistent time base.

                    To get great drawing performance use multiple graphical objects drawn on a
                    single control, instead of multiple controls.

                    Regards,
                    Frank Hileman

                    check out VG.net: http://www.vgdotnet.com
                    Animated vector graphics system
                    Integrated Visual Studio .NET graphics editor


                    "ham-z" <hamz-3e@/**/yahoo.com> wrote in message
                    news:eO7oaI45EH A.3820@TK2MSFTN GP11.phx.gbl...[color=blue]
                    > Nick Malik [MSFT] wrote:
                    > creating sth alive...look at this if you have MSDN 2003 installed:
                    > ms-help://MS.MSDNQTR.2003 APR.1033/dndllpro/html/msdn_frogfly1.h tm[/color]


                    Comment

                    • Dennis

                      #11
                      Re: How to make this better and faster?

                      Are you saying that BitBlt is not any faster than .drawimage? It seems
                      faster to me and I have read articles on the web that also say it's much
                      faster.

                      "Herfried K. Wagner [MVP]" wrote:
                      [color=blue]
                      > "Dennis" <Dennis@discuss ions.microsoft. com> schrieb:[color=green]
                      > > You might want to check into the API routine BitBlt. It copies rectangle
                      > > shapes from and to graphics objects. It's very, very fast. You could
                      > > draw
                      > > your images directly on the form using the Paint event.[/color]
                      >
                      > I doubt that this will be much faster than 'Graphics.DrawI mage[Unscaled]'.
                      >
                      > --
                      > M S Herfried K. Wagner
                      > M V P <URL:http://dotnet.mvps.org/>
                      > V B <URL:http://dotnet.mvps.org/dotnet/faqs/>
                      >
                      >[/color]

                      Comment

                      • Herfried K. Wagner [MVP]

                        #12
                        Re: How to make this better and faster?

                        "Dennis" <Dennis@discuss ions.microsoft. com> schrieb:[color=blue]
                        > Are you saying that BitBlt is not any faster than .drawimage? It seems
                        > faster to me and I have read articles on the web that also say it's much
                        > faster.[/color]

                        I didn't check it in all details, but I assume that 'DrawImageUnsca led' is
                        approx. as fast as 'BitBlt' because it is a wrapper around 'BitBlt'.

                        --
                        M S Herfried K. Wagner
                        M V P <URL:http://dotnet.mvps.org/>
                        V B <URL:http://dotnet.mvps.org/dotnet/faqs/>

                        Comment

                        • Tommy

                          #13
                          Re: How to make this better and faster?

                          Don't assume.
                          DrawImageUnscal ed is not a wrapper around BitBlt. DrawImageUnscal ed
                          just calls DrawImage. DrawImage calls the native function
                          GdipDrawImageI, which isn't as fast as BitBlt.
                          GdipDrawImageI uses GDI+, BitBlt uses GDI. GDI+ isn't hardware
                          accelerated, GDI is.

                          Comment

                          • Herfried K. Wagner [MVP]

                            #14
                            Re: How to make this better and faster?

                            "Tommy" <tommy.carlier@ telenet.be> schrieb:[color=blue]
                            > Don't assume.
                            > DrawImageUnscal ed is not a wrapper around BitBlt. DrawImageUnscal ed
                            > just calls DrawImage. DrawImage calls the native function
                            > GdipDrawImageI[/color]

                            You are right. IIRC what I said was written in "Profession al C#" published
                            by Wrox. ILDASM shows that 'DrawImageUnsca led' simply calls 'DrawImage',
                            and 'DrawImage' is a wrapper around 'GdipDrawImageR ectI'. Thank you for
                            making me aware of that.

                            --
                            M S Herfried K. Wagner
                            M V P <URL:http://dotnet.mvps.org/>
                            V B <URL:http://dotnet.mvps.org/dotnet/faqs/>

                            Comment

                            • Tommy

                              #15
                              Re: How to make this better and faster?

                              I don't use ILDASM, I use Reflector. It's much better than ILDASM, and
                              it decompiles the assembly in the language you want (included
                              languages: C#, VB.NET, IL, Delphi). http://www.aisto.com/roeder/dotnet

                              Comment

                              Working...