Multithreading C++\Cli在执行(冗长的)方法期间未对窗体进行状态更新

Multithreading C++\Cli在执行(冗长的)方法期间未对窗体进行状态更新,multithreading,c++-cli,Multithreading,C++ Cli,我有一个执行模拟的方法。在此模拟中,调用了几种耗时的方法。我想在模拟执行期间将一些状态计数器和状态值输出到表单上的文本框。然而,这不起作用。模拟完成后,仅报告最终状态 我认为踩踏可能是一种方式,但我发现很难将状态更新之间的代码放在一个单独的方法中(没有(返回)参数??),这样就可以使用ThreadStart等调用它。注意:在我得到的方法中有参数“线程委托构造函数的参数无效;委托目标必须是指向成员函数的指针” 以下是模拟方法的代码: void Simulation::runSimulation(G

我有一个执行模拟的方法。在此模拟中,调用了几种耗时的方法。我想在模拟执行期间将一些状态计数器和状态值输出到表单上的文本框。然而,这不起作用。模拟完成后,仅报告最终状态

我认为踩踏可能是一种方式,但我发现很难将状态更新之间的代码放在一个单独的方法中(没有(返回)参数??),这样就可以使用
ThreadStart
等调用它。注意:在我得到的方法中有参数“线程委托构造函数的参数无效;委托目标必须是指向成员函数的指针”

以下是模拟方法的代码:

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++;
    }
}
void模拟::运行模拟(基因组^aGenome,器官^anOrgan,int-nCycl,int-nMem)
{
int i,j,k;
bool terminateLoop=false;
双重性;
双重平均性;
双重健身;
int vCells,vGenes;//无效细胞/基因
bool-nDivLimit;
布尔-恩塞尔极限;
i=0;//循环计数器
而(itextBox3->Text=i.ToString();
j=0;//填充成员计数器
sumFitness=0.0;
而(j添加(aGenome);
genomePool[j]->generateRandomGenome();//耗时的方法
anOrgan->initOrgan();
nDivLimit=false;
nCellLimit=false;
k=0;//器官循环计数器
而((kmaxCycles | anOrgan->maxCycles==-1)和&!nDivLimit和&!nCellLimit)
{
anOrgan->processGeneExpressions(nDivLimit,nCellLimit);//非常耗时的方法
k++;
}
gFitness=anOrgan->getOrganFitness(vCells,vGenes);//耗时的方法
基因组池[j]->gFitness=gFitness;
sumFitness+=gFitness;
avgFitness=sumgfitness/(双倍)(j+1);
f1->textBox5->Text=j.ToString();
f1->textBox7->Text=gFitness.ToString();
f1->textBox6->Text=avgFitness.ToString();
j++;
}
i++;
}
}
状态更新将发送到Form1,Form1作为
f1
转发到此类。即使是在实际处理开始之前调用的对textBox3的第一次更新,也只有在方法完成时才输出

问题: 1) 穿线是唯一的出路吗?
2) 如何将状态更新(
f1->textBox
调用)之间的代码移动到可以使用
ThreadStart
等调用的单独方法中?

调用f1->在while(j 这将更新您的显示,并允许GUI与用户交互


偶尔尝试调用Refresh,比如每5、10、50或100个循环调用一次,直到您找到一个频率,使您的GUI能够根据需要响应—但不再如此。

这对于UI更新的发生方式非常重要。UI只有在UI线程空闲时才被绘制,然后重新进入dispatcher循环。您可以调用textbox“启动”date()方法强制绘制。最多只能工作几秒钟。谢谢Hans。这确实有效。别忘了将此问题标记为已回答(复选标记)。还不能投票(代表10),但“f1->Refresh()”确实有效,适用于所有文本框,因此比Hans建议的每个文本框的“textBox->Update()”要短一些。