1
I’m trying to make a visual representation of random number generation using UWP
. Basically, there are X rectangles on a screen, each represents a number, so the first rectangle is 0, the second 1 and so on. The class that represents these rectangles has these attributes:
public class Representer
{
public int TimesChosen { get; set; }
public int NumberRepresented { get; set; }
public double CurrentProportion { get; set; }
public double RectangleWidth { get; set; }
public Rectangle Rect { get; set; }
.
.
}
Each time a number is generated, the corresponding Representative gets the variable "TimesChosen
" incremented in 1. This access is done through a dictionary in the Manager class:
public class Manager
{
public Canvas CanvasManaged { get; set; }
public double NumbersGenerated { get; set; }
public readonly int Range;
public Dictionary<int, Representer> Representers = new Dictionary<int, Representer>();
.
.
}
When a number is generated, the height of these rectangles should be updated to the corresponding ratio, for example, if I have 5 rectangles and they all have their numbers generated an equal amount of time, the proportion of all rectangles is 20%, and so the height should be 20% of the screen. The way I’m trying to update the whole proportion of rectangles and their heights is through an event. Every time a number is generated, the manager generates an event that informs all rectangles that must be updated:
public async void GenerateNumber(TextBlock Iterations)
{
Random Random = new Random();
while (true)
{
int Number = Random.Next(this.Range);
this.NumbersGenerated += 1;
Representers[Number].TimesChosen += 1;
await Task.Run(() =>
{
OnNumberGenerated();
});
Iterations.Text = this.NumbersGenerated.ToString();
}
}
public virtual void OnNumberGenerated()
{
NumberGenerated?.Invoke(this, new ManagerArgs { NumbersGenerated = this.NumbersGenerated, CanvasManaged = this.CanvasManaged });
}
The implementation of OnNumberGenerated
in the Representatives is:
public async void OnNumberGenerated(object source, ManagerArgs e)
{
this.CurrentProportion = this.TimesChosen / e.NumbersGenerated;
await Task.Run(async () =>
{
await e.CanvasManaged.Dispatcher.RunAsync(CoreDispatcherPriority.Normal, () =>
{
this.Rect.Height = e.CanvasManaged.Height * this.CurrentProportion;
this.Rect.Fill = new SolidColorBrush(Color.FromArgb(255, Convert.ToByte(255 * this.CurrentProportion), Convert.ToByte(255 * (1 - this.CurrentProportion)), 0));
});
});
}
The problem is that the performance is really bad, for example if I have 1000 rectangles, the refresh rate is about 10 rectangles / second. This led me to think: in what way the implementations of OnNumberGenerated
are being called after the event is generated? Is there a way to make these implementations to be called asynchronously or in threads
? There is a way to improve the performance of the programme?