(背景) 我正在創建一個股票市場模擬程序,以進一步提高我的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
'MSDN建議針對這一點,執行安全however'似乎是一個奇怪的假設應用程序崩潰。不是說它造成它,但它可能是。 –
你應該仔細研究一下使用'Task'來完成你的後臺工作。在2016年直接在.NET中創建線程基本上是聞所未聞的,而且總是值得眉目。另一方面,任務與課程相同。 –
您的樣本庫存量是多少?它包含什麼樣的數據? – fofik