0

I'm using a gift inside of a picturebox while the form is loading. At every opening, it s putting a random image on the picturebox

PictureBox1.Image = My.Resources.ResourceManager.GetObject("load" & r.Next(1, 12))

The problem is that when I start the program, the gift is not really properly animated, kind of suffering some lag. I tried using backgroundworker with:

   Public Async Function MyFunction() As Task
    Await Task.Run(Sub()
                       PictureBox1.Image = My.Resources.ResourceManager.GetObject("load" & r.Next(1, 12))

                   End Sub)

End Function

and inside of form_load I'm calling the function:

 Await MyFunction()

This unfortunately, doesn't solve the freezing of the gif. How can I solve this?

Mattia
  • 258
  • 7
  • 25
  • You cannot access a Control from a ThreadPool Thread: `Await Task.Run(Sub() PictureBox1.Image = ...`. Plus, it's completely useless, you're just assigning a resource object to a Property (which is an **object**, you're not event casting it to `Image`. Set `Option Strict On` as soon as possible). Move that assignment to the `Form.Shown` event. If the `GIF` is not animated correctly, it's because you're blocking the UI Thread with *something synchronous*. – Jimi Sep 26 '20 at 01:30
  • With *the first assignment* I mean: `PictureBox1.Image = DirectCast(My.Resources.ResourceManager.GetObject("load" & r.Next(1, 12)), Image)` + I assume you're aware that `r.Next(1, 12)` gets you values between 1 and 11. – Jimi Sep 26 '20 at 01:37
  • Hi Jimi, I want to know more about that. I'm moving the assignment `PictureBox1.Image = DirectCast(My.Resources.ResourceManager.GetObject("load" & r.Next(1, 12)), Image)` to the Form.show event. Now, I have other code in this form2 that it's supposed to be kind of splash screen. Could loading of form1 influence form2 loading? Form2 is the first shown. Now, should I populate the picturebox (which is picking from resources file an image x from 1 to 11 to show on picturebox on purpose) on a different thread? if yes, could you suggest a link for documentation? Thanks – Mattia Sep 26 '20 at 02:24
  • I don't know what other code you have there and what this code is doing. You haven't shown any of it. -- A Thread / Task won't do anything here: the Image animation is an internal functionality of the PictureBox Control, which executes in the UI Thread -- Note that VB.Net has built-in support for Splash *screen*. Try to use this functionality if you're not, instead of rolling your own. – Jimi Sep 26 '20 at 02:33
  • I want to add, not sure if it s relevant, that gif freeze in the first 3 seconds which I think it comes from the loading of form1 cause the cursor is loading for that amount of time. – Mattia Sep 26 '20 at 02:49
  • Despite of what form1 is loading in async o sync, is there way to load form2 async? I just read an article on https://stackoverflow.com/questions/38067128/better-way-of-doing-splash-screen which make me think also splash screen needs a background worker/thread/task to run like a separate software. Am I making a mistake using form1 as initial form but hiding it for first 5 seconds and in the while showing a splash screen in a " async "form? – Mattia Sep 26 '20 at 02:56
  • It's not the Form that should *load asynchronously* (don't even try that), it's the code that's blocking the UI Thread that should be run in a worker thread. What kind of *thread*, depends on what that code is operating on. If you understand how a BackgroundWorker works, use that. Use its reporting capabilities to updated Controls, if necessary. – Jimi Sep 26 '20 at 03:09
  • Hi Jimi, so basically If I understood right, if form1.load or shown event is empty then this will prevent any form2 freeze at its loading? – Mattia Sep 26 '20 at 12:33
  • Perhaps [this code sample](https://github.com/karenpayneoregon/async-basics-vb/tree/master/SplashFormExample) might help which works in this case with one gif, will work with random images too. There is Thread.Sleep(5000) to simulate some work. – Karen Payne Sep 26 '20 at 12:36
  • so basically If I understood right, if form1.load or shown event is empty then this will prevent any form2 freeze at its loading? It is a sign of good developing when you make a completely async software from start to end? Does developers use async all the time for better soffware displaying? How can you do when in form load you have to do lots of things but you cannot update UI from any other thread other than the UI thread? What if when you have to use a lot of objects in form load? – Mattia Sep 26 '20 at 12:42
  • Is it just the code in form load that is blocking things? In my case, all the other code need to be done just when user click a button, so in form load stay not that much code. – Mattia Sep 26 '20 at 12:42
  • 1
    Hi karen, something like this? Private Async Sub SplashForm_Load(sender As Object, e As EventArgs) Handles MyBase.Load Await Task.Run(Async Function() PictureBox1.InvokeIfRequired( Sub(pictureBox) PictureBox1.Image = DirectCast(My.Resources.ResourceManager.GetObject("load" & r.Next(1, 12)), Image) End Sub) Await Task.Delay(500) End Function) End Sub – Mattia Sep 26 '20 at 12:45
  • What do you think? Even if this goes against what jimi said about not using an async load – Mattia Sep 26 '20 at 12:47
  • Read the notes here: [Start a Task in the Form Shown event](https://stackoverflow.com/a/60571698/7444103). Just updated the descriptions. Test those methods. – Jimi Sep 27 '20 at 03:18

0 Answers0