0

I am plotting a Julia Set in a panel named pnlGraph that is 601 x 601 pixels. I determine the color of each pixel in a Paint event, and plot the entire Set using the command pnlGraph.Refresh(). It takes the PC about a minute to plot all 361,201 pixels. If I see an error early in the process of the panel refreshing, I would like to be able to interrupt the refresh and do something else.

I have searched the internet and found something called DoEvents() that I am unable to use properly. Can anyone help me use DoEvents() or some other method to interrupt a panel in mid-refresh in order to save time? Thank you.

  • 1
    You should post your code, to see how you're handling this. For example, drawing of the surface of a Panel is not a great idea to begin with. A PictureBox or a flat Label are better choices. To repaint a Control, you usually call `Invalidate()`, not `Refresh()` etc. -- I'm not saying that `DoEvent()` is not used in this context, a Mandelbrot set is a couple of closed nested loop, but it may get better. – Jimi Mar 25 '22 at 04:05
  • 1
    When you encounter an "error" just use `Exit Sub` to immediately stop whatever you were doing... – Idle_Mind Mar 25 '22 at 05:01
  • What specific errors might you get while refreshing the panel? – Xingyu Zhao Mar 25 '22 at 07:50
  • `DoEvents()` (or equivalent code) has the effect of running through the current message queue for whatever window and running the appropriate processing code. This is helpful for remaining responsive, but it can result in re-entrant code (two different paths through the same code at the same time) which can be surprising and result in bugs. Ultimately, sure, you can interrupt any routine you control. Set up a boolean flag to watch, and if it changes to a "stop this" state, as previously suggested, exit out of the routine. – Craig Mar 25 '22 at 13:39
  • Please provide enough code so others can better understand or reproduce the problem. – Community Mar 25 '22 at 14:07
  • 1
    @Craig The *problem* here is that to generate and draw a Mandelbrot you need at least two nested loops. If this is done in the UI Thread, you know what happens. A bool flag cannot be set interacting with the UI, since it freezes in the meanwhile. You can offload the work to a Threadpool Thread (and stop the work using a CancellationToken, eventually). All depends on how you want to present the results (all at once, using a Bitmap; progressive, using, e.g., `SetPixel()` - quite slow) -- Using `DoEvents()` in the UI - in this context - doesn't cause reentrancy problems; if handled correctly. – Jimi Mar 25 '22 at 14:07
  • @Jimi, it took me a while to digest what you said and to search out how to do a bitmap. That idea worked wonders, cutting down the time to display the image by over 80%. If I use fewer iterations, the bitmap appears almost instantaneously. That means I don't have to wait over a minute to display each image, which solves my problem. Thank you very much! – Earl Whitney Jun 10 '22 at 02:55

1 Answers1

0

@Jimi's suggestion to use a bitmap instead of the paint event worked wonders, cutting down the time to display the image by over 80%. If I use fewer iterations, the bitmap appears almost instantaneously. That means I don't have to wait over a minute to display each image, which solves my problem.

Here's the code I developed in a separate project to create the bitmap. It's more complicated in the program I wanted it for, but this cuts out all the code that is not needed to solve my problem. I deleted the Panel and replaced it with a PictureBox called pbxFractal. That's where I placed the bitmap image. Very cool stuff.

Private Sub Form1_Load(sender As Object, e As EventArgs) Handles Me.Load

    Dim i, j, i1, j1 As Int16

    Dim fractalBitmap As Bitmap = New Bitmap(601, 601)

    Dim pixColor As Color

    For i = 0 To 600
        For j = 0 To 600

            i1 = i Mod 256
            j1 = j Mod 256
            pixColor = Color.FromArgb(255, i1, j1, Math.Abs(i1 - j1))
            fractalBitmap.SetPixel(i, j, pixColor)

        Next j
    Next i

    pbxFractal.Image = fractalBitmap

End Sub
Adrian Mole
  • 49,934
  • 160
  • 51
  • 83