2016-07-26 97 views
0

(背景) 我正在創建一個股票市場模擬程序,以進一步提高我的C#知識。 我以前用Java創建過這個程序。C#MultiThreading導致類型'System.OutOfMemoryException'未處理的異常

(問題) 在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(),所以我不認爲問題出在那裏。

這是拋出的錯誤:

類型「System.OutOfMemoryException的」未處理的異常出現在mscorlib.dll

我還沒有從中繼器中打開的任何額外的線程分開,中繼器通常拋出這個錯誤時,提前(希望)

達到例如7

謝謝

編輯:

感謝@RichardSzalay和@MichaelThePotato我一直在使用這個例子來實現一個計時器:https://stackoverflow.com/a/12535833/6639187

+0

'MSDN建議針對這一點,執行安全however'似乎是一個奇怪的假設應用程序崩潰。不是說它造成它,但它可能是。 –

+0

你應該仔細研究一下使用'Task'來完成你的後臺工作。在2016年直接在.NET中創建線程基本上是聞所未聞的,而且總是值得眉目。另一方面,任務與課程相同。 –

+0

您的樣本庫存量是多少?它包含什麼樣的數據? – fofik

回答

1

一個你使用的方法,但還沒有上市很可能會抱着一種引用。使用內存分析器查找您的應用程序泄漏的位置RedGate會執行14天的免費試用。

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

相關問題