|
dev
newsgroups
|
|||||||||||||||||||||||
|
|||||||||||||||||||||||
How to make this better and faster?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,system.windows.forms.dll,system.drawing.dll,microsoft.visualbasic.dll /t:winexe /main:form1 '----------------------------------- Start of CODE Imports System.Math imports Microsoft.VisualBasic 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. InitializeComponent() 'Add any initialization after the InitializeComponent() 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.Dispose() End If End If MyBase.Dispose(disposing) End Sub 'Required by the Windows Form Designer Private components As System.ComponentModel.IContainer '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.Diagnostics.DebuggerStepThrough()> Private Sub InitializeComponent() ' 'Form1 ' Me.AutoScaleBaseSize = 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(ByVal sender As Object, ByVal e As System.EventArgs) Handles MyBase.Click CreateOBJ() End Sub Sub CreateOBJ() Dim myRec As Rec = New Rec(Me.CreateGraphics, 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.Add(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(ByVal sender As Object, ByVal e As System.EventArgs) 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------------ 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. Show quoteHide quote "ham-z" wrote: > 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,system.windows.forms.dll,system.drawing.dll,microsoft.visualbasic.dll > /t:winexe /main:form1 > > '----------------------------------- Start of CODE > > Imports System.Math > imports Microsoft.VisualBasic > 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. > InitializeComponent() > > 'Add any initialization after the InitializeComponent() 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.Dispose() > End If > End If > MyBase.Dispose(disposing) > End Sub > > 'Required by the Windows Form Designer > Private components As System.ComponentModel.IContainer > > '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.Diagnostics.DebuggerStepThrough()> Private Sub > InitializeComponent() > ' > 'Form1 > ' > Me.AutoScaleBaseSize = 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(ByVal sender As Object, ByVal e As > System.EventArgs) Handles MyBase.Click > CreateOBJ() > End Sub > > > Sub CreateOBJ() > Dim myRec As Rec = New Rec(Me.CreateGraphics, 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.Add(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(ByVal sender As Object, ByVal e As > System.EventArgs) 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" <Den***@discussions.microsoft.com> schrieb: I doubt that this will be much faster than 'Graphics.DrawImage[Unscaled]'.> 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. -- M S Herfried K. Wagner M V P <URL:http://dotnet.mvps.org/> V B <URL:http://dotnet.mvps.org/dotnet/faqs/> 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. Show quoteHide quote "Herfried K. Wagner [MVP]" wrote: > "Dennis" <Den***@discussions.microsoft.com> schrieb: > > 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. > > I doubt that this will be much faster than 'Graphics.DrawImage[Unscaled]'. > > -- > M S Herfried K. Wagner > M V P <URL:http://dotnet.mvps.org/> > V B <URL:http://dotnet.mvps.org/dotnet/faqs/> > > "Dennis" <Den***@discussions.microsoft.com> schrieb: I didn't check it in all details, but I assume that 'DrawImageUnscaled' is > 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. 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/> Don't assume.
DrawImageUnscaled is not a wrapper around BitBlt. DrawImageUnscaled 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. "Tommy" <tommy.carl***@telenet.be> schrieb: You are right. IIRC what I said was written in "Professional C#" published > Don't assume. > DrawImageUnscaled is not a wrapper around BitBlt. DrawImageUnscaled > just calls DrawImage. DrawImage calls the native function > GdipDrawImageI by Wrox. ILDASM shows that 'DrawImageUnscaled' simply calls 'DrawImage', and 'DrawImage' is a wrapper around 'GdipDrawImageRectI'. 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/> 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 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 Ham,
Nice crossposting, however the in my opinion most right newsgroup for this question is not in it. microsoft.public.dotnet.framework.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 Show quoteHide quote "ham-z" <hamz-3e@/**/yahoo.com>. >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,system.windows.forms.dll,system.drawing.dll,microsoft.visualbasic.dll > /t:winexe /main:form1 > > '----------------------------------- Start of CODE > > Imports System.Math > imports Microsoft.VisualBasic > 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. > InitializeComponent() > > 'Add any initialization after the InitializeComponent() 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.Dispose() > End If > End If > MyBase.Dispose(disposing) > End Sub > > 'Required by the Windows Form Designer > Private components As System.ComponentModel.IContainer > > '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.Diagnostics.DebuggerStepThrough()> Private Sub > InitializeComponent() > ' > 'Form1 > ' > Me.AutoScaleBaseSize = 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(ByVal sender As Object, ByVal e As > System.EventArgs) Handles MyBase.Click > CreateOBJ() > End Sub > > > Sub CreateOBJ() > Dim myRec As Rec = New Rec(Me.CreateGraphics, 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.Add(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(ByVal sender As Object, ByVal e As > System.EventArgs) 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------------ > > > 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 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..... Show quoteHide quote "Rulin Hong" <RulinH***@discussions.microsoft.com> wrote in message news:DC5D3BAD-0BD3-4255-8B5B-3EFB8175F4CD@microsoft.com... > 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 > 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. -- Show quoteHide quote--- Nick Malik [MSFT] MCSD, CFPS, Certified Scrummaster http://blogs.msdn.com/nickmalik 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 /r:system.dll,system.windows.forms.dll,system.drawing.dll,microsoft.visualbanews:Ot3Btv15EHA.2608@TK2MSFTNGP10.phx.gbl... > 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] > sic.dll Show quoteHide quote > /t:winexe /main:form1 > > '----------------------------------- Start of CODE > > Imports System.Math > imports Microsoft.VisualBasic > 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. > InitializeComponent() > > 'Add any initialization after the InitializeComponent() 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.Dispose() > End If > End If > MyBase.Dispose(disposing) > End Sub > > 'Required by the Windows Form Designer > Private components As System.ComponentModel.IContainer > > '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.Diagnostics.DebuggerStepThrough()> Private Sub > InitializeComponent() > ' > 'Form1 > ' > Me.AutoScaleBaseSize = 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(ByVal sender As Object, ByVal e As > System.EventArgs) Handles MyBase.Click > CreateOBJ() > End Sub > > > Sub CreateOBJ() > Dim myRec As Rec = New Rec(Me.CreateGraphics, 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.Add(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(ByVal sender As Object, ByVal e As > System.EventArgs) 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------------ > > > Nick Malik [MSFT] wrote:
> OK, so you have a form that **VERY QUICKLY** moves boxes at random around Nice hint, but my PB object is responsible for it's own movement. It should> 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. have a built-in timer in order to move > I'm not sure what you are trying to prove with this graphics exercise. creating sth alive...look at this if you have MSDN 2003 installed:ms-help://MS.MSDNQTR.2003APR.1033/dndllpro/html/msdn_frogfly1.htm > Also, your timer is declared in the object, not in the form. The means How? each object is responsible for its own movement....> 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 Nice suggestion.> 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. Thanks anyway for help. 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 misunderstandings. In a simulation of multiple actors, the simplest single threaded approach is to loop through all the actors when a Windows.Forms.Timer 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, QueryPerformanceCounter (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 Show quoteHide quote "ham-z" <hamz-3e@/**/yahoo.com> wrote in message news:eO7oaI45EHA.3820@TK2MSFTNGP11.phx.gbl... > Nick Malik [MSFT] wrote: > creating sth alive...look at this if you have MSDN 2003 installed: > ms-help://MS.MSDNQTR.2003APR.1033/dndllpro/html/msdn_frogfly1.htm 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 Show quoteHide quote "ham-z" <hamz-3e@/**/yahoo.com> wrote in message news:Ot3Btv15EHA.2608@TK2MSFTNGP10.phx.gbl... >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,system.windows.forms.dll,system.drawing.dll,microsoft.visualbasic.dll > /t:winexe /main:form1 > > '----------------------------------- Start of CODE > > Imports System.Math > imports Microsoft.VisualBasic > 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. > InitializeComponent() > > 'Add any initialization after the InitializeComponent() 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.Dispose() > End If > End If > MyBase.Dispose(disposing) > End Sub > > 'Required by the Windows Form Designer > Private components As System.ComponentModel.IContainer > > '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.Diagnostics.DebuggerStepThrough()> Private Sub > InitializeComponent() > ' > 'Form1 > ' > Me.AutoScaleBaseSize = 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(ByVal sender As Object, ByVal e As > System.EventArgs) Handles MyBase.Click > CreateOBJ() > End Sub > > > Sub CreateOBJ() > Dim myRec As Rec = New Rec(Me.CreateGraphics, 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.Add(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(ByVal sender As Object, ByVal e As > System.EventArgs) 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------------ > > >
Other interesting topics
How to screen scrap a non-browser based object?
.NET competes with java-script Direction and suggestions needed How to create a new app instance with Process multiline toolbarbuttons Extracting runat server objects from aspx using VS.Net 2003 with Framework 2 beta MSIL FileSystemWatcher event fired only once System.Net.Socket and Linux Server |
|||||||||||||||||||||||