如何停止从窗口调用的类函数.c#中的表单应用程序
本文关键字:表单 应用程序 类函数 窗口 调用 何停止 | 更新日期: 2023-09-27 18:01:46
我用c#写了一个遗传算法,为CAD程序(Rhino)创建几何图形。该算法包含在一个库中,我为CAD程序编写了一个小的windows窗体插件。调用GA.run()函数将返回一个填充ListBox的List,选择一个Item将在CAD程序中生成几何图形。
在windows窗体应用程序中,我创建了GA类的一个实例,通过单击开始按钮,从窗体中收集各种GA设置,并调用GA.run()函数。现在,由于这是一个遗传算法,它在返回之前会运行几代。但是,我希望有在运行所有代之前停止函数的选项。我如何从我的插件内停止GA.run()函数?当我点击运行按钮时,windows窗体应用程序"暂停",直到GA.run()返回其列表…
我猜有一个更好的方式调用GA.run()?. .
停止按钮代码:
private void runBtn_Click(object sender, EventArgs e)
{
// get rule settings
SettingsHolder gaSettings = new SettingsHolder();
gaSettings.GenMaxrun = (int)gensNUD.Value;
..
gaAlgo = new GA(algoSettings);
try
{
currentPopulation = paretoAlgo.run();
}
catch(Exception e)
{
MessageBox.Show("exc while trying run: " + e);
}
// iterate list and list in form
popLB.Items.Clear();
foreach (Chromosome c in currentPopulation)
{
popLB.Items.Add(new KeyValuePair<String, int> (c.present(), id));
}
}
GA.run ():
public List<Chromosome> run()
{
try
{
initPop();
// loop until genMaxrun or no new achieved
do
{
// create geometries from chromosomes
foreach (Chromosome chromo in population)
{
chromo.embryogeny(Settings);
}
// step 2:Fitness
// union the population and archive
unionPop = new List<Chromosome>(population);
unionPop.AddRange(archive);
calculateDomination(unionPop);
foreach(Chromosome chromo in unionPop)
{
chromo.calculateRawFitness(unionPop);
chromo.calculateDensity(unionPop);
chromo.setFitness();
}
environmentalSelection();
// increase Generation +1
generation += 1;
// create new population...
population = reproduction(generation);
}
while (generation < Settings.GenMaxrun);
}
catch (Exception e)
{
throw new Exception("Error in SPEA run", e);
}
return archive;
}
是否有一种方法可以在run()的while循环中添加检查?表单应用程序中的停止按钮单击事件是否会改变GA的参数(因为它正在执行run()函数),而run()函数将中止?或者我可以从GA.run()检查调用者中的参数吗?或者我需要使用线程吗?
如果我需要更准确地解释什么,请告诉我。
欢呼,"
虽然您可以在循环中使用Application.DoEvents
做一些事情,但您最好让该代码在Task
或BackgroundWorker中运行。这两种方法都会在一个单独的线程上启动遗传算法,使窗体处于活动状态。然后你可以有一个Cancel
按钮来停止后台处理。
BackgroundWorker
完全支持取消和定期向表单报告进度。请查看该页面的示例。我想它会做你想要的。
Task
是一个更好的解决方案,因为它使用了新的线程模型。一般来说,Task
是我用于生产程序的,因为它有一些我觉得有用的其他选项,但BackgroundWorker
工作得很好。 有一种方法可以做到你的CA被控制得很紧。windows消息泵没有执行,所以要获得用户刚刚点击取消按钮,你必须在GA循环中调用DoEvents,然后轮询取消被点击的标志。相信我,你不会想这样做的,它是低效的,脆弱的,混乱的,完全的PIA单元测试。
你需要的是一个线程。您还需要决定在GA工作时是否可以使用表单。如果不是,就吐一句"工作……"样式形式,并在其上放置一个扣。这是在你的UI线程中,所以它会得到点击,然后你停止GA线程。还有很多关于线程的东西,但是。net有一些很好的东西来处理这些东西。BackgroundWorker会是一个很好的查询。