Started learning to code.
Have a console writing a 10 by ten grid of numbers randomly increasing in value.
Tried to do same in a form (DataGridView).
It works fine but there is no window until calcs are finished (I had to put a limit in – instead of an infinite loop).
I came here and read about refresh and doevent – but they dramatically slow everything down. But at least I can see the calcs happening.
I’ve tried to get my head around backgroundworker and I’m afraid I can’t. If I’m in a loop to calculate – how do I separate those calcs from a screen update.
EDIT : Followed Nico’s help(Thanks!!) and got this. Much better, but still laggy with big numbers. But a rocket with small numbers.
Any help to make faster?
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
namespace stackoverflowTest
{
public partial class Form1 : Form
{
Random rnd = new Random((Int32)DateTime.Now.Ticks);
private static int numSides = 8;
int numDice=2;
private int numRolls = 100000000;
private int max = 1;
private int min = 0;
private int diff = 0;
private double pdiff = 0d;
int[] array = new int[numSides *numSides];
public Form1()
{
InitializeComponent();
}
private void Form1Load(object sender, EventArgs e)
{
SetupDataForm1();
SetupDataForm2();
var bw = new BackgroundWorker();
bw.DoWork += BwDoWork;
bw.RunWorkerAsync(); //Start the worker
}
private void BwDoWork(object sender, DoWorkEventArgs e)
{
for (int rolls = 1; rolls < numRolls+1; rolls++)
{
// Roll two dice and increase that slot in the table
int y = Dice.Roll(numSides, rnd);
int x = Dice.Roll(numSides, rnd);
int k = Convert.ToInt32(dataGridView1.Rows[x].Cells[y].Value);
dataGridView1.Rows[x].Cells[y].Value = k + 1;
//Enter table into an array to work out max/min etc later
for (int i = 0; i < (numSides * numSides); i++)
{
int row = i / numSides;
int col = i % numSides;
array[i] = Convert.ToInt32(dataGridView1.Rows[row].Cells[col].Value);
}
max = array.Max();
min = array.Min();
diff = max - min;
if (max > 0) pdiff = (((double)diff / (max)) * 100);
dataGridView2.Rows[0].Cells[0].Value = rolls;
dataGridView2.Rows[1].Cells[0].Value = max;
dataGridView2.Rows[2].Cells[0].Value = min;
dataGridView2.Rows[3].Cells[0].Value = diff;
dataGridView2.Rows[4].Cells[0].Value = pdiff.ToString("0.000");
dataGridView2.Rows[5].Cells[0].Value = (array.Average()).ToString("0");
dataGridView2.Rows[6].Cells[0].Value = ((array.Average()/rolls)*100).ToString(("0.0000000"));
}
}
private void SetupDataForm1()
{
dataGridView1.Font = new Font("Microsoft Sans Serif", 6F);
dataGridView1.RowTemplate.Height = 11;
//Add Columns
for (int i = 0; i < numSides; i++)
{
dataGridView1.Columns.Add(i.ToString(), (i+1).ToString());
dataGridView1.Columns[i].Width = 35;
}
// Add Rows
for (int i = 0; i < numSides; i++)
{
dataGridView1.Rows.Add();
if (i % 2 != 0)
{
dataGridView1.Rows[i].DefaultCellStyle.BackColor = Color.LightGray;
}
dataGridView1.Rows[i].HeaderCell.Value = ((i+1)*10).ToString();
}
}
private void SetupDataForm2()
{
dataGridView2.Font = new Font("Microsoft Sans Serif", 8F);
dataGridView2.RowTemplate.Height = 16;
//Add Columns
for (int i = 0; i < 1; i++)
{
dataGridView2.Columns.Add(i.ToString(), "");
dataGridView2.Columns[i].Width = 65;
}
// Add Rows
for (int i = 0; i < numSides; i++)
{
dataGridView2.Rows.Add();
if (i % 2 != 0)
{
dataGridView2.Rows[i].DefaultCellStyle.BackColor = Color.LightGray;
}
}
dataGridView2.Rows[0].HeaderCell.Value = "Rolls";
dataGridView2.Rows[1].HeaderCell.Value = "Max";
dataGridView2.Rows[2].HeaderCell.Value = "Min";
dataGridView2.Rows[3].HeaderCell.Value = "Diff";
dataGridView2.Rows[4].HeaderCell.Value = "%";
dataGridView2.Rows[5].HeaderCell.Value = "Avg";
dataGridView2.Rows[6].HeaderCell.Value = "Av%";
}
public class Dice
{
public static int Roll(int numberOfSides, Random rnd)
{
return rnd.Next(0, numberOfSides);
}
}
}
}
If there is no window, you perform the calculations in the form’s constructor. To make the form visible before starting the calculation, put the code in the form’s Load event. Therefore double click the event in the form’s properties window and a method will be created. Put your code into this method.
If you want to use a background worker, the procedure is similar. However, you need to create the
Backgroundworker. E.g. in code:If you start typing that, Visual Studio suggests to create a method for the event. Press Tab twice to generate it and you’ll basically get the following code:
Put your calculation code in the bw_DoWork method an it will be executed in the background without affecting the user interface.