如何停止从窗口调用的类函数.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()检查调用者中的参数吗?或者我需要使用线程吗?

如果我需要更准确地解释什么,请告诉我。

欢呼,"

如何停止从窗口调用的类函数.c#中的表单应用程序

虽然您可以在循环中使用Application.DoEvents做一些事情,但您最好让该代码在Task或BackgroundWorker中运行。这两种方法都会在一个单独的线程上启动遗传算法,使窗体处于活动状态。然后你可以有一个Cancel按钮来停止后台处理。

BackgroundWorker完全支持取消和定期向表单报告进度。请查看该页面的示例。我想它会做你想要的。

有些人说Task是一个更好的解决方案,因为它使用了新的线程模型。一般来说,Task是我用于生产程序的,因为它有一些我觉得有用的其他选项,但BackgroundWorker工作得很好。

有一种方法可以做到你的CA被控制得很紧。windows消息泵没有执行,所以要获得用户刚刚点击取消按钮,你必须在GA循环中调用DoEvents,然后轮询取消被点击的标志。相信我,你不会想这样做的,它是低效的,脆弱的,混乱的,完全的PIA单元测试。

你需要的是一个线程。您还需要决定在GA工作时是否可以使用表单。如果不是,就吐一句"工作……"样式形式,并在其上放置一个扣。这是在你的UI线程中,所以它会得到点击,然后你停止GA线程。

还有很多关于线程的东西,但是。net有一些很好的东西来处理这些东西。BackgroundWorker会是一个很好的查询。