为什么我的代码在form1中变得递归?

时间:2018-11-21 11:01:21

标签: c# winforms recursion out-of-memory

我一直在使用C#进行一些软件开发,并且运行良好,但是截至昨天晚上,我注意到它在加载图像时抛出了内存异常错误。 我试图减小图像尺寸,但后来意识到“声明老鼠”被反复打印到控制台上,在控制台上只能出现一次。

深入挖掘一些断点,我发现它进入allRats = new Drawing(HousePicBox, DekuPicBox, BakuPicBox); //THIS HAS BECOME RECURSIVE, WTF处的图形构造函数 但是它似乎没有在构造函数中运行代码,而是跳回到form1()的开头。

我已将所有代码包含在程序计数器所涉及的文件中。

// --------------------------------------------- ------ FORM1.CS ----------------------------------------- --------------------

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;

// This is the code for your desktop app.
// Press Ctrl+F5 (or go to Debug > Start Without Debugging) to run your app.

namespace XMLRats5
{
    public partial class Form1 : Form
    {
        // These are here as they are referred to by various functions for different reasons 
        string MazakSourceURL = "http://mtconnect.mazakcorp.com:5609";      // Gives us a human friendly reference to the HTML 
        string NISTSourceURL = "https://smstestbed.nist.gov/vds/current";  // Gives us a human friendly reference to the HTML 

    public PollTimer statusPoller;

    public static Drawing allRats;

    ImageRat Deku;
    ImageRat Bakugo;

    NISTDataSet CurrentNIST;
    MazakDataSet CurrentMazak;


    public Form1()
    {
        Console.WriteLine("Declaring Rats..."); // Is being called recursively :( ?????????????
        ImageRat.Deku = new Rat(false, 0, 0, true, 0); // Declares Deku
        ImageRat.Bakugo = new Rat(false, 800, 0, true, 0); // Declares Bakugo
        Console.WriteLine("Initialising");
        InitializeComponent(); // Constructs the graphics which make up the 'state 0'   
        Console.WriteLine("Declaring image");
        allRats = new Drawing(HousePicBox, DekuPicBox, BakuPicBox); //THIS HAS BECOME RECURSIVE, WTF
        Console.WriteLine("Clearing Image");
        allRats.ClearRats();
        Console.WriteLine("Displaying House");
        HousePicBox.Show();
        //allRats.DrawRats(ImageRat.deku.Awake, ImageRat.bakugo.Awake);    
        Console.WriteLine("Form 1 Initiated, please proceed.");
    }

    private void NISTDataLinkLabel_LinkClicked(object sender, LinkLabelLinkClickedEventArgs e)
    {
        // This link takes you to the 'current' NIST testbed data feed page
        System.Diagnostics.Process.Start(NISTSourceURL);
    }

    private void MAZAKDataLinkLabel_LinkClicked(object sender, LinkLabelLinkClickedEventArgs e)
    {
        // This link takes you to the raw XML published by Mazaks HCN6800 labelled 5609
        System.Diagnostics.Process.Start(MazakSourceURL);
    }

    public void StatusCheckButton_Click(object sender, EventArgs e) // Here we should check that the machine tools are feeding live data
    {
        // Clear the rat picture boxes as they 'stick' when already shown
        DekuPicBox.Hide();
        BakuPicBox.Hide();

        string MazakStatus = "Unchecked";
        string NISTStatus = "Unchecked";


        try
        {
            CurrentMazak = MTFunctions.PollMazak();
            MazakStatus = CurrentMazak.Status;
            if (MazakStatus == "AVAILABLE") { ImageRat.Deku.Awake = true; }
        }
        catch (Exception MazakLookupFailed)
        {
            Console.WriteLine("Could not retrieve Mazak Data", MazakLookupFailed);
            MazakStatus = "Lookup Failed"; // This will later refer to the xml path for running status 
        }


        try
        {
            CurrentNIST = MTFunctions.PollNIST();
            NISTStatus = CurrentNIST.Status;
            if (NISTStatus == "AVAILABLE") { ImageRat.Bakugo.Awake = true; }
        }
        catch (Exception NISTLookupFailed)
        {
            Console.WriteLine("Could not Retrieve NIST Data: ", NISTLookupFailed);
            NISTStatus = "Lookup Failed";
            ImageRat.Bakugo.Awake = false;
        }

        string MessageString = " Mazak : " + MazakStatus + "\n NIST     : " + NISTStatus;

        if ((ImageRat.Deku.Awake == true) & (ImageRat.Bakugo.Awake == true))   // Both Online
        {
            HousePicBox.Image = XMLRats5.Properties.Resources.bothsleep; // SLeeping rat shows machine online but not feeding data

        } // Empty Box
        if ((ImageRat.Deku.Awake == true) & (ImageRat.Bakugo.Awake == false))  // NIST offline 
        {
            HousePicBox.Image = XMLRats5.Properties.Resources.bakusleep;
            DekuPicBox.Show(); // Not neccessary but prevents bugs
        } // Put Bakug in box, deku out
        if ((ImageRat.Deku.Awake == false) & (ImageRat.Bakugo.Awake == true))  // Mazak Offline
        {
            HousePicBox.Image = XMLRats5.Properties.Resources.dekuSleep;
            BakuPicBox.Show(); // Not neccessary but prevents bugs
        } // Put deku in box, bakugo out
        if ((ImageRat.Deku.Awake == false) & (ImageRat.Bakugo.Awake == false)) // Both Offline
        {
            HousePicBox.Image = XMLRats5.Properties.Resources.nosleep;
        } // Put rats in box


        MessageBox.Show(MessageString, "Machine Status"); // We need to pass information gained through XPath to first argument            
    }

    public void WakeRatsButton_Click(object sender, EventArgs e)
    {
        MessageBox.Show("This 'wakes the rats' (Begins data stream)");
        // We need to poll Mazak and NIST here to determine which images to draw.
        MazakDataSet checkM = MTFunctions.PollMazak();
        NISTDataSet checkN = MTFunctions.PollNIST();
        if (checkM.Status == "AVAILABLE")
        {
            ImageRat.Deku.Awake = true;
            DekuPicBox.Show();
        }
        else { ImageRat.Deku.Awake = false; }
        if (checkN.Status == "AVAILABLE")
        {
            BakuPicBox.Show();
            ImageRat.Bakugo.Awake = true;
        }
        else { ImageRat.Bakugo.Awake = false; }


        allRats.DrawRats(ImageRat.Deku.Awake, ImageRat.Bakugo.Awake); // Should move the boys out of the box
        // Here the draw function successfully relocates the rats, so why does this not work from the timer?

        statusPoller = new PollTimer(2000, true); //Initiate a timer driven function which polls the data sets
        // Timer Driven function draws rats
    }

    public void DebugInstructionsLabel_Click(object sender, EventArgs e)
    { }

    public void titleLabel_Click(object sender, EventArgs e) { }

    public void SleepRatsButton_Click(object sender, EventArgs e)
    {
        MessageBox.Show("This 'puts the rats to bed' (Closes data stream)");

        try  // Stop Polling timer function
        {
            statusPoller.Stop();
            statusPoller.Dispose();
            Console.Write("Stream closed successfully");
        }
        catch { Console.WriteLine("Could not stop polling. Were the rats actually 'awake'?"); }

        // Draw rats in house   
        DekuPicBox.Hide(); // Rat is no longer active
        BakuPicBox.Hide(); // Rat is no longer active
        HousePicBox.Image = XMLRats5.Properties.Resources.nosleep; // Show empty box

        //allRats.Paint();
    }

    private void Form1_Load(object sender, EventArgs e)
    {

    }

    private void HousePicBox_Click(object sender, EventArgs e)
    {

    }

    private void DekuPicBox_Click(object sender, EventArgs e)
    {
        // Proves that problem with movement is because DekuPicBox needs to be changed, not allRats.dekuPic....
        System.Drawing.Point DekuCoord = new System.Drawing.Point(ImageRat.Deku.PosX, ImageRat.Deku.PosY);      // Create a 'System Point' for Deku
        DekuPicBox.Location = DekuCoord;
        Console.WriteLine("~~~~~~~~Deku moved to " + DekuCoord + " ~~~~~~~~");
    }

    private void BakuPicBox_Click(object sender, EventArgs e)
    {
        System.Drawing.Point BakuCoord = new System.Drawing.Point(ImageRat.Bakugo.PosX, ImageRat.Bakugo.PosY);      // Create a 'System Point' for Deku
        BakuPicBox.Location = BakuCoord;
        Console.WriteLine("~~~~~~~~Bakugo moved to " + BakuCoord + " ~~~~~~~~");
    }



    public void Refresh(int boi) // Better bloody relocate those pics boii
    {
        if (boi == 0)
        {
            System.Drawing.Point BakuCoord = new System.Drawing.Point(ImageRat.Bakugo.PosX, ImageRat.Bakugo.PosY);      // Create a 'System Point' for Deku
            DekuPicBox.Location = BakuCoord;
        }
        else
        {
            System.Drawing.Point DekuCoord = new System.Drawing.Point(ImageRat.Deku.PosX, ImageRat.Deku.PosY);      // Create a 'System Point' for Deku
            DekuPicBox.Location = DekuCoord;
        }

    }

}
}

// --------------------------------------------- -FORM1.Designer.CS -------------------------------------------- ------------

namespace XMLRats5
{
    partial class Form1
    {
        /// <summary>
        /// Required designer variable.
        /// </summary>
        private System.ComponentModel.IContainer components = null;

    /// <summary>
    /// Clean up any resources being used.
    /// </summary>
    /// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
    protected override void Dispose(bool disposing)
    {
        if (disposing && (components != null))
        {
            components.Dispose();
        }
        base.Dispose(disposing);
    }

    #region Windows Form Designer generated code

    /// <summary>
    /// Required method for Designer support - do not modify
    /// the contents of this method with the code editor.
    /// </summary>
    private void InitializeComponent()
    {
        this.MAZAKDataLinkLabel = new System.Windows.Forms.LinkLabel();
        this.DebugInstructionsLabel = new System.Windows.Forms.Label();
        this.StatusCheckButton = new System.Windows.Forms.Button();
        this.TitleLabel = new System.Windows.Forms.Label();
        this.WakeRatsButton = new System.Windows.Forms.Button();
        this.SleepRatsButton = new System.Windows.Forms.Button();
        this.NISTDataLinkLabel = new System.Windows.Forms.LinkLabel();
        this.BakuPicBox = new System.Windows.Forms.PictureBox();
        this.HousePicBox = new System.Windows.Forms.PictureBox();
        this.DekuPicBox = new System.Windows.Forms.PictureBox();
        ((System.ComponentModel.ISupportInitialize)(this.BakuPicBox)).BeginInit();
        ((System.ComponentModel.ISupportInitialize)(this.HousePicBox)).BeginInit();
        ((System.ComponentModel.ISupportInitialize)(this.DekuPicBox)).BeginInit();
        this.SuspendLayout();
        // 
        // MAZAKDataLinkLabel
        // 
        this.MAZAKDataLinkLabel.AutoSize = true;
        this.MAZAKDataLinkLabel.Location = new System.Drawing.Point(1287, 985);
        this.MAZAKDataLinkLabel.Margin = new System.Windows.Forms.Padding(4, 0, 4, 0);
        this.MAZAKDataLinkLabel.Name = "MAZAKDataLinkLabel";
        this.MAZAKDataLinkLabel.Size = new System.Drawing.Size(179, 25);
        this.MAZAKDataLinkLabel.TabIndex = 0;
        this.MAZAKDataLinkLabel.TabStop = true;
        this.MAZAKDataLinkLabel.Text = "View Mazak Data";
        this.MAZAKDataLinkLabel.LinkClicked += new System.Windows.Forms.LinkLabelLinkClickedEventHandler(this.MAZAKDataLinkLabel_LinkClicked);
        // 
        // DebugInstructionsLabel
        // 
        this.DebugInstructionsLabel.AutoSize = true;
        this.DebugInstructionsLabel.Location = new System.Drawing.Point(1066, 524);
        this.DebugInstructionsLabel.Margin = new System.Windows.Forms.Padding(4, 0, 4, 0);
        this.DebugInstructionsLabel.Name = "DebugInstructionsLabel";
        this.DebugInstructionsLabel.Size = new System.Drawing.Size(623, 50);
        this.DebugInstructionsLabel.TabIndex = 1;
        this.DebugInstructionsLabel.Text = "Press \'Check Machine\' to ensure a device is running, otherwise \n don\'t expect muc" +
"h activity from the rats!";
        this.DebugInstructionsLabel.Click += new System.EventHandler(this.DebugInstructionsLabel_Click);
        // 
        // StatusCheckButton
        // 
        this.StatusCheckButton.Location = new System.Drawing.Point(1271, 658);
        this.StatusCheckButton.Margin = new System.Windows.Forms.Padding(4);
        this.StatusCheckButton.Name = "StatusCheckButton";
        this.StatusCheckButton.Size = new System.Drawing.Size(195, 54);
        this.StatusCheckButton.TabIndex = 2;
        this.StatusCheckButton.Text = "Check Machine Status";
        this.StatusCheckButton.UseVisualStyleBackColor = true;
        this.StatusCheckButton.Click += new System.EventHandler(this.StatusCheckButton_Click);
        // 
        // TitleLabel
        // 
        this.TitleLabel.AutoSize = true;
        this.TitleLabel.Font = new System.Drawing.Font("Microsoft Sans Serif", 16F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
        this.TitleLabel.Location = new System.Drawing.Point(1255, 382);
        this.TitleLabel.Margin = new System.Windows.Forms.Padding(4, 0, 4, 0);
        this.TitleLabel.Name = "TitleLabel";
        this.TitleLabel.Size = new System.Drawing.Size(211, 51);
        this.TitleLabel.TabIndex = 3;
        this.TitleLabel.Text = "XML Rats";
        this.TitleLabel.Click += new System.EventHandler(this.titleLabel_Click);
        // 
        // WakeRatsButton
        // 
        this.WakeRatsButton.Location = new System.Drawing.Point(1271, 775);
        this.WakeRatsButton.Margin = new System.Windows.Forms.Padding(4);
        this.WakeRatsButton.Name = "WakeRatsButton";
        this.WakeRatsButton.Size = new System.Drawing.Size(195, 54);
        this.WakeRatsButton.TabIndex = 4;
        this.WakeRatsButton.Text = "Wake Rats";
        this.WakeRatsButton.UseVisualStyleBackColor = true;
        // 
        // SleepRatsButton
        // 
        this.SleepRatsButton.Location = new System.Drawing.Point(1271, 885);
        this.SleepRatsButton.Margin = new System.Windows.Forms.Padding(4);
        this.SleepRatsButton.Name = "SleepRatsButton";
        this.SleepRatsButton.Size = new System.Drawing.Size(195, 54);
        this.SleepRatsButton.TabIndex = 5;
        this.SleepRatsButton.Text = "Sleep Rats";
        this.SleepRatsButton.UseVisualStyleBackColor = true;
        // 
        // NISTDataLinkLabel
        // 
        this.NISTDataLinkLabel.AutoSize = true;
        this.NISTDataLinkLabel.Location = new System.Drawing.Point(1287, 1054);
        this.NISTDataLinkLabel.Margin = new System.Windows.Forms.Padding(4, 0, 4, 0);
        this.NISTDataLinkLabel.Name = "NISTDataLinkLabel";
        this.NISTDataLinkLabel.Size = new System.Drawing.Size(162, 25);
        this.NISTDataLinkLabel.TabIndex = 6;
        this.NISTDataLinkLabel.TabStop = true;
        this.NISTDataLinkLabel.Text = "View NIST Data";
        // 
        // BakuPicBox
        // 
        this.BakuPicBox.Image = global::XMLRats5.Properties.Resources.bakuTransSmall;
        this.BakuPicBox.Location = new System.Drawing.Point(2092, 1388);
        this.BakuPicBox.Name = "BakuPicBox";
        this.BakuPicBox.Size = new System.Drawing.Size(632, 424);
        this.BakuPicBox.SizeMode = System.Windows.Forms.PictureBoxSizeMode.StretchImage;
        this.BakuPicBox.TabIndex = 9;
        this.BakuPicBox.TabStop = false;
        // 
        // HousePicBox
        // 
        this.HousePicBox.Image = global::XMLRats5.Properties.Resources.nosleep;
        this.HousePicBox.Location = new System.Drawing.Point(1057, 1388);
        this.HousePicBox.Name = "HousePicBox";
        this.HousePicBox.Size = new System.Drawing.Size(632, 424);
        this.HousePicBox.SizeMode = System.Windows.Forms.PictureBoxSizeMode.StretchImage;
        this.HousePicBox.TabIndex = 8;
        this.HousePicBox.TabStop = false;
        // 
        // DekuPicBox
        // 
        this.DekuPicBox.Image = global::XMLRats5.Properties.Resources.DekuBackgroundTransparent;
        this.DekuPicBox.Location = new System.Drawing.Point(12, 1388);
        this.DekuPicBox.Name = "DekuPicBox";
        this.DekuPicBox.Size = new System.Drawing.Size(632, 424);
        this.DekuPicBox.SizeMode = System.Windows.Forms.PictureBoxSizeMode.StretchImage;
        this.DekuPicBox.TabIndex = 7;
        this.DekuPicBox.TabStop = false;
        this.DekuPicBox.Click += new System.EventHandler(this.DekuPicBox_Click);
        // 
        // Form1
        // 
        this.AutoScaleDimensions = new System.Drawing.SizeF(12F, 25F);
        this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
        this.ClientSize = new System.Drawing.Size(2736, 1824);
        this.Controls.Add(this.BakuPicBox);
        this.Controls.Add(this.HousePicBox);
        this.Controls.Add(this.DekuPicBox);
        this.Controls.Add(this.NISTDataLinkLabel);
        this.Controls.Add(this.SleepRatsButton);
        this.Controls.Add(this.WakeRatsButton);
        this.Controls.Add(this.TitleLabel);
        this.Controls.Add(this.StatusCheckButton);
        this.Controls.Add(this.DebugInstructionsLabel);
        this.Controls.Add(this.MAZAKDataLinkLabel);
        this.Margin = new System.Windows.Forms.Padding(4);
        this.Name = "Form1";
        this.Text = "Form1";
        ((System.ComponentModel.ISupportInitialize)(this.BakuPicBox)).EndInit();
        ((System.ComponentModel.ISupportInitialize)(this.HousePicBox)).EndInit();
        ((System.ComponentModel.ISupportInitialize)(this.DekuPicBox)).EndInit();
        this.ResumeLayout(false);
        this.PerformLayout();

    }

    #endregion

    private System.Windows.Forms.LinkLabel MAZAKDataLinkLabel;
    private System.Windows.Forms.Label DebugInstructionsLabel;
    private System.Windows.Forms.Button StatusCheckButton;
    private System.Windows.Forms.Label TitleLabel;
    private System.Windows.Forms.Button WakeRatsButton;
    private System.Windows.Forms.Button SleepRatsButton;
    private System.Windows.Forms.LinkLabel NISTDataLinkLabel;
    public System.Windows.Forms.PictureBox DekuPicBox;
    public System.Windows.Forms.PictureBox HousePicBox;
    public System.Windows.Forms.PictureBox BakuPicBox;
}

}

// --------------------------------------------- ---------------- DRAWING.CS ----------------------------

using System;
using System.Collections.Generic;
using System.Text;
using System.Threading.Tasks;
using System.IO;
using System.Reflection;
using System.Drawing;
using System.Windows.Forms;


namespace XMLRats5
{
    public class Drawing : Form1
    {
        private PictureBox HouseImage;
        private PictureBox DekuImage;
        private PictureBox BakuImage;

        public Drawing(PictureBox house, PictureBox deku, PictureBox baku)
        {
            HouseImage  = house;
            DekuImage   = deku;
            BakuImage   = baku;
        } // Code is jumping back to form1 call :S


        public void ClearRats()
        {
            //DekuImage.Image.Dispose();
            //BakuImage.Image.Dispose();
            //HouseImage.Image.Dispose();

            HouseImage.Hide();
            DekuImage.Hide();
            BakuImage.Hide();
        }

        public void RePaint()
        {
            //BakuImage.Paint();
            //DekuImage.Paint();
            //HouseImage.Paint();
        }

        public void DrawRats(bool DekuWake, bool BakuWake) // Call this function using active status of 2 machines
        {
            this.ClearRats();

            DekuPicBox.SuspendLayout();
            BakuPicBox.SuspendLayout();
            HousePicBox.SuspendLayout();

            System.Drawing.Point DekuCoord = new System.Drawing.Point(ImageRat.Deku.PosX, ImageRat.Deku.PosY);      // Create a 'System Point' for Deku
            System.Drawing.Point BakuCoord = new System.Drawing.Point(ImageRat.Bakugo.PosX, ImageRat.Bakugo.PosY);  // Create a 'System Point' for Bakugo
            Console.WriteLine("Randomly Generated Point Assigned (Deku):" + DekuCoord);
            Console.WriteLine("Randomly Generated Point Assigned (Baku):" + BakuCoord);

            if (DekuWake == false)
            {
                DekuImage.Hide();
                if (BakuWake == false)
                {
                    BakuPicBox.Hide();
                    HousePicBox.Image = XMLRats5.Properties.Resources.bothsleep;// set HouseImage to both sleep
                }
                else
                {
                    BakuPicBox.Location = BakuCoord;                    
                    BakuPicBox.Show();                    
                    HousePicBox.Image = XMLRats5.Properties.Resources.dekuSleep; //Set HouseImage to DekuSleep 
                }
            }
            else //DekuWake == true
            {
                DekuImage.Show();
                if (BakuWake == true)
                {
                    HousePicBox.Image = XMLRats5.Properties.Resources.nosleep;//Set House image to nosleep
                    DekuPicBox.Location = DekuCoord;
                    DekuPicBox.Show();
                    BakuPicBox.Location = BakuCoord;
                    BakuPicBox.Show();
                }    
                else
                {
                    BakuPicBox.Hide();
                    HousePicBox.Image = XMLRats5.Properties.Resources.bakusleep;// Set house image to bakusleep
                    DekuPicBox.Location = DekuCoord;
                    DekuPicBox.Show();
                }
            }

            HousePicBox.Show(); // Out here as it should always happen


        }

    }



}

老实说,我对为什么它一直跳回到form1的开头感到困惑。 我弄坏了什么?

1 个答案:

答案 0 :(得分:3)

由于Drawing是从Form1派生的,并且您在Form1构造函数中创建了Drawing的实例-这将导致Form1构造函数被再次调用,这将导致另一个Drawing实例的创建,从而导致...... .....-

请注意,基类构造函数在派生类构造函数中的代码之前被调用-这就是为什么您不了解Drawing构造函数中的代码的原因。