0

コードの学習を開始しました。

値がランダムに増加する 10 x 10 のグリッドをコンソールに書き込みます。フォーム(DataGridView)で同じことをしようとしました。正常に動作しますが、計算が終了するまでウィンドウはありません (無限ループの代わりに制限を設定する必要がありました)。

私はここに来て、refresh と doevent について読みましたが、すべてが劇的に遅くなります。しかし、少なくとも計算が行われていることがわかります。

バックグラウンドワーカーについて頭を悩ませようとしましたが、残念ながらできません。計算がループしている場合、これらの計算を画面の更新から分離するにはどうすればよいですか。

編集:ニコの助けに従って(ありがとう!!)、これを手に入れました。はるかに優れていますが、大きな数ではまだ遅れています。でも数の少ないロケット。より速くするための助けはありますか?

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 += 

入力を開始すると、VisualStudioはイベントのメソッドを作成することを提案します。Tabキーを2回押して生成すると、基本的に次のコードが表示されます。

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 に答える