(背景) 我正在创建一个股市仿真程序,以进一步提升我的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
答案 0 :(得分:1)
您使用但未列出的方法之一可能会持续引用。使用内存分析器查找应用程序泄漏的位置RedGate进行为期14天的免费试用。
如果您的应用没有泄漏,那么它只是试图一次性加载太多数据。
答案 1 :(得分:0)
您还可以使用免费工具ClrDbg来检查.Net应用程序的堆并找出内存问题的原因 https://sourceforge.net/projects/clrdbg/