Member Avatar for nblackburn

I have a function that renders roughly 100-200 images on a canvas, ever since moving my applications resources to an archive and reading them in from memory i am getting a white screen for a second or so whilst it renders the images.

This wasnt happening when i was using a flat file system but i would like to keep the archive system as it has its easier to manage. What would be the best way of handling the more intensive functions like this whilst decreasing the white screen or eliminating it entirely.

I have tried utilising async but that makes it so you can see each of the images being rendered and i dont want that as i would like it to happen before the window is shown.

The code for the intensive function is as follows...

internal static void RenderStars(Canvas canvas, int density = 200)
{
    List<string> getStars = Resource.GetFiles("images/scene/stars", "star_*.png");
    var random = new Random();
    for (int x = 0; x < density; x++)
    {
        string starImage = getStars[random.Next(0, getStars.Count)];
        int starSize = random.Next(1, 10);
        int starOpacity = random.Next(10, 50);
        int starX = random.Next(0, (int) canvas.ActualWidth);
        int starY = random.Next(0, (int) canvas.ActualHeight);
        var star = new Image
        {
            Name = (x < 10) ? "Star_0" + x : "Star_" + x,
            Source = Core.StreamImage(starImage),
            Height = starSize,
            Width = starSize,
            Opacity = (double) starOpacity/100
        };
        canvas.Children.Add(star);
        Canvas.SetLeft(star, starX);
        Canvas.SetTop(star, starY);
        Panel.SetZIndex(star, 0);
    }
}

Any help would be great, thanks so much :)

One thing that might help is loading the list getStars before you call the function and either making it public or passing it to the function. Also instead of creating all those variables in the for loop, calling the random function directly might gain some speed(i.e.Height = random.Next(1, 10),Width = Height. Another thing you could try is creating an array equal to your density count that contains values for all the star properties fully randomized, and having public or passing that to your function. That way your function only has to iterate through the array and draw the stars. Depending on the time interval between changes, you might be able to do the preprocessing asynchronously, while the timer is waiting for the next interval. Just a few thought hope they help.

Member Avatar for nblackburn

Thank you for the helpful suggestions, i will certainly take them into account in trying to get a performance boost from the method.

Member Avatar for nblackburn

One thing that might help is loading the list getStars before you call the function and either making it public or passing it to the function. Also instead of creating all those variables in the for loop, calling the random function directly might gain some speed(i.e.Height = random.Next(1, 10),Width = Height. Another thing you could try is creating an array equal to your density count that contains values for all the star properties fully randomized, and having public or passing that to your function. That way your function only has to iterate through the array and draw the stars. Depending on the time interval between changes, you might be able to do the preprocessing asynchronously, while the timer is waiting for the next interval. Just a few thought hope they help.

Regarding some of the variables in the function, some of the values need to be of equal value to other values and placing them inside the image handler wouldn't guarentee this.

I am confident in saying that the perfomance issue lies in the fact i am getting the images from a zip file as i didnt have this issue when i was using the flat file structure.

Member Avatar for nblackburn

ddanbe That sounds like a good way of tackling it, but i have no idea how to use them as i am fairly new to C#.

Member Avatar for nblackburn

Perhaps i was to cache all the paths to the applications resources in a list or array, then it will be already available by the time the function is called. This could reduce the time taken for the function to complete as it is not having to do that each time the function is ran?

I am confident in saying that the perfomance issue lies in the fact i am getting the images from a zip file as i didnt have this issue when i was using the flat file structure.

Did you try moving line 3 out of the function and putting it right after the intitialize() command? Don't forget to make it public.

Well, lets say I'm a bit of an advanced newbie! Never used the Backgroundworker myself! I currently have no need to use it. But if I would, I would probably read this

Member Avatar for nblackburn

Did you try moving line 3 out of the function and putting it right after the intitialize() command? Don't forget to make it public.

I have tried you suggestion but to no such luck. I will keep trying to work around this and report back if i find a solution that works.

Took another look at your code. If the slowdown isn't in initializing the list, it's probably in line 15 Source = Core.StreamImage(starImage),. How many images do you have? Is it feasible to load those images at startup into a list? That would definitely speed things up. Can you show the code where you set up the stream reader?

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.