C#多线程导致类型为';System.OutOfMemoryException';

本文关键字:System OutOfMemoryException 多线程 类型 | 更新日期: 2023-09-27 17:58:41

(背景)我正在创建一个股票市场模拟程序来进一步提高我的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

C#多线程导致类型为';System.OutOfMemoryException';

您使用但尚未列出的方法之一可能会保留引用。使用内存探查器找出您的应用程序泄漏的位置。RedGate提供14天免费试用。

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

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