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
您使用但尚未列出的方法之一可能会保留引用。使用内存探查器找出您的应用程序泄漏的位置。RedGate提供14天免费试用。
如果你的应用程序没有泄漏,那么它只是试图一次加载太多数据。
您还可以使用免费工具ClrDbg来检查.Net应用程序的堆,并找出内存问题的原因https://sourceforge.net/projects/clrdbg/