Frage

I have a method that executes a simulation. In this simulation several time consuming methods are called. I want to output some status counters and status values to textBoxes on a Form during execution of the simulation. However, this doesn't work. Only the final status is reported after completion of the simulation.

I think treading may be the way to go, but I find it hard put the code between the status updates into a separate method (with no (return) arguments??), so that it can be called using ThreadStart etc. Note: with arguments in the method I get "thread invalid argument for delegate constructor; delegate target needs to be a pointer to a member function".

Here's the code of the simulation method:

void Simulation::runSimulation(Genome^ aGenome, Organ^ anOrgan, int nCycl, int nMem)
{
    int i, j, k;
    bool terminateLoop = false;
    double gFitness;
    double avgFitness;
    double sumFitness;
    int vCells, vGenes; //  void cells / genes
    bool nDivLimit;
    bool nCellLimit;

    i = 0;  // cylcle counter
    while (i < nCycl && !terminateLoop)
    {
        f1->textBox3->Text = i.ToString();
        j = 0; // population member counter
        sumFitness = 0.0;
        while (j < nMem && !terminateLoop)
        {
            genomePool->Add(aGenome);
            genomePool[j]->generateRandomGenome();  // time consuming method
            anOrgan->initOrgan();

            nDivLimit = false;
            nCellLimit = false;
            k = 0;  // organ loop counter
            while ( (k < anOrgan->maxCycles || anOrgan->maxCycles == -1) && !nDivLimit && !nCellLimit)
            {
                anOrgan->processGeneExpressions(nDivLimit, nCellLimit); // very time consuming method
            k++;
            }

            gFitness = anOrgan->getOrganFitness(vCells, vGenes);    // time consuming method

            genomePool[j]->gFitness = gFitness;
            sumFitness += gFitness;
            avgFitness = sumFitness / (double) (j+1);

            f1->textBox5->Text = j.ToString();
            f1->textBox7->Text = gFitness.ToString();
            f1->textBox6->Text = avgFitness.ToString();

            j++;
        }
        i++;
    }
}

The status updates are to be sent to Form1 which is forwarded to this class as f1. Even the first update to textBox3, which is called before the real processing begins, is only output when the method has finished.

Questions: 1) Is threading the (only) way to go? 2) How do I move the code between the status updates (f1->textBox calls) into a separate method that can be called using ThreadStart etc.?

War es hilfreich?

Lösung

Call f1->Refresh at the end of the while (j < nMem && !terminateLoop) loop.

This will update your display and allow the GUI to interact with the user.

Experiment with calling Refresh only occasionally, say every 5, 10, 50 or 100 loops, until you find a freuency that makes you GUI as responsive as you need - but no more.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top