C#MultiThreading导致类型'System.OutOfMemoryException'的未处理异常

时间:2016-07-26 10:30:24

标签: c# multithreading out-of-memory

(背景) 我正在创建一个股市仿真程序,以进一步提升我的C#知识。 我以前用Java创建了这个程序。

(问题) 在Java中,我能够创建一个新线程,以便每隔x个时间循环并更新我的GUI标签。我研究了在C#中执行此操作的方法并遇到了计时器,这对我来说不起作用,因此我采用了多线程。

启动表单后,我创建一个新线程

    /// <summary>
    /// stock emulation startup
    /// </summary>
    public stockEmu()
    {
        CheckForIllegalCrossThreadCalls = false; //if this is true, then cross-thread changes cannot be made (repeater cannot set labels if true)

        initializeValues(); //this will set the startup values e.g stock prices and user money

        ThreadStart loopThread = new ThreadStart( repeater );   //opens a new thread
        Thread openThread = new Thread( loopThread );       //opens a new thread
        openThread.Start();                             //opens a new thread

        InitializeComponent(); //initializes the form

        this.updateLabels(); //needs to be after initializecomponent or null exception is thrown (because the labels are not drawn yet)
    }

这是新的线程方法:

    /// <summary>
    /// infinite loop to execute every x seconds (using a new thread)
    /// repeater uses cross-thread operation(s) and so CheckForIllegalCrossThreadCalls has been set to false
    /// MSDN recommends against this, it is executed safely however
    /// </summary>
    private void repeater()
    {
        while( true )
        {
            Thread.Sleep( 5000 ); //sleep (pause) the thread for 5 seconds
            instance = instance + 1; //add to the current instance (this is used to display what "day" we're on
            changePrices(); //change the prices of the stocks
            updateLabels(); //update the form's labels to display the new values
        }
    }

以下是转发器每5秒调用一次的方法

    /// <summary>
    /// this will change the prices every x seconds based on current prices etc
    /// </summary>
    private void changePrices()
    {
        marketController mC = new marketController();
        for( int i = 0 ; i < stocks.Length ; i++ )
        {
            mC.changePrices( stocks [ i ] , i ); //mc for marketController, object reference, change prices will calc the price changes
        }
        return;
    }

mC.changePrices实际上并没有做任何事情,但它不会卡在那里。

    /// <summary>
    /// method used to update all display labels every x seconds (based on repeater)
    /// </summary>
    public void updateLabels()
    {
        try
        {
            this.userMoneyLabel.Text = "Your money: " + this.getUserMoney().ToString(); //changes the user's money label
            this.currentDayLabel.Text = "Day: " + this.getInstance().ToString(); //changes the day label
            this.setStocksCombined(); //sets the array of combined stock prices and stock names
            this.stockListBox.Items.Clear(); //clear the list box because it will constantly stack the items
            this.stockListBox.Items.AddRange( stocksCombined ); //adds the combined array to the list box (stocks + stockNames)
        }
        catch( Exception e )
        {
            MessageBox.Show( "Error: " + e );
        }
    }

所有相关标签都更新,这个问题在我添加setStocksCombined()之前也一直存在,所以我不相信问题就在那里。

这是引发的错误:

  

mscorlib.dll中出现未处理的“System.OutOfMemoryException”类型异常

除了转发器之外,我没有打开任何其他线程,转发器在到达实例7时通常会抛出此错误。

提前致谢(希望如此)

编辑:

感谢@RichardSzalay和@MichaelThePotato我使用此示例实现了一个计时器:https://stackoverflow.com/a/12535833/6639187

2 个答案:

答案 0 :(得分:1)

您使用但未列出的方法之一可能会持续引用。使用内存分析器查找应用程序泄漏的位置RedGate进行为期14天的免费试用。

如果您的应用没有泄漏,那么它只是试图一次性加载太多数据。

答案 1 :(得分:0)

您还可以使用免费工具ClrDbg来检查.Net应用程序的堆并找出内存问题的原因 https://sourceforge.net/projects/clrdbg/