簡體   English   中英

C#MultiThreading導致類型為'System.OutOfMemoryException'的未處理異常

[英]C# MultiThreading is causing unhandled exception of type 'System.OutOfMemoryException'

(背景)我正在創建一個股票仿真程序,以進一步提高我的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

您使用但未列出的一種方法可能會保留參考。 使用內存分析器找出您的應用程序泄漏的地方RedGate提供14天免費試用。

如果您的應用程序沒有泄漏,那么它只是嘗試一次性加載太多數據。

您還可以使用免費工具ClrDbg檢查.Net應用程序的堆,並找出導致內存問題的原因https://sourceforge.net/projects/clrdbg/

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM