0

开始学习编码。

有一个控制台写一个 10 x 10 的数字网格,数值随机增加。试图在表单(DataGridView)中做同样的事情。它工作正常,但在计算完成之前没有窗口(我必须限制 - 而不是无限循环)。

我来到这里阅读有关 refresh 和 doevent 的信息 - 但它们大大减慢了一切。但至少我可以看到发生的计算。

我试图了解背景工作者,但恐怕我做不到。如果我在一个循环中进行计算 - 我如何将这些计算与屏幕更新分开。

编辑:遵循 Nico 的帮助(谢谢!!)并得到了这个。好多了,但仍然滞后于大数字。但是火箭数量很少。有什么帮助可以加快速度吗?

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);
        }
    }
}

}

4

1 回答 1

0

如果没有窗口,则在表单的构造函数中执行计算。要在开始计算之前使表单可见,请将代码放在表单的 Load 事件中。因此,双击表单属性窗口中的事件,将创建一个方法。将您的代码放入此方法中。

如果要使用后台工作程序,过程类似。但是,您需要创建Backgroundworker. 例如在代码中:

private void Form1_Load(object sender, EventArgs e)
{
    var bw = new BackgroundWorker();
    bw.DoWork += 

如果您开始输入,Visual Studio 建议为该事件创建一个方法。按两次 Tab 生成它,你基本上会得到以下代码:

private void Form1_Load(object sender, EventArgs e)
{
    var bw = new BackgroundWorker();
    bw.DoWork += bw_DoWork;
    bw.RunWorkerAsync(); //Start the worker
}

void bw_DoWork(object sender, DoWorkEventArgs e)
{
    throw new NotImplementedException(); //remove this
}

将您的计算代码放在 bw_DoWork 方法中,它将在后台执行,而不会影响用户界面。

于 2012-12-16T23:51:01.413 回答