我已经开发了C#应用程序,创建了线程数量,经过一段时间后,它将异常作为系统抛出。创建新线程时出现OutOfMemoryException。任何处理此异常的想法。不使用try-catch。如何增加内存空间或如何从内存中释放线程。这件事处理得很快。
private void DataChangeHandler(object sender, DataChangeEventArgs e)
{
try
{ update3(e);
}
catch { }
}
public void update3(object h)
{
try
{
if (h != null)
{
DataChangeEventArgs e = (DataChangeEventArgs)h;
OdbcConnection con128 = new OdbcConnection(LocalConnection.GetLocalConnetionString());
int counter = 0;
OdbcCommand cmd;
string UpdateQuery = "";
string query1 = "";
while (counter < e.sts.Length)
{
object val = e.sts[counter].DataValue;
int hour = e.sts[counter].TimeStampNet.Hour;
int minute = e.sts[counter].TimeStampNet.Minute;
int second = e.sts[counter].TimeStampNet.Second;
int millisecond = e.sts[counter].TimeStampNet.Millisecond;
int year = e.sts[counter].TimeStampNet.Year;
int month = e.sts[counter].TimeStampNet.Month;
int day = e.sts[counter].TimeStampNet.Day;
DateTime sdate = new DateTime(year, month, day, hour, minute, second, millisecond);
string date = sdate.ToString("dd-MM-yyyy HH:mm:ss.fff");
DateTime dt = DateTime.FromFileTime(e.sts[counter].TimeStamp);
query1 += "select '" + val + "' as DTvalue ,'" + date + "' as DTdatelogged1,'" + OpcGroup.QualityToString(e.sts[counter].Quality) + "' as DTquality ,'" + dt + "' as DTtimestamp ,'" + e.sts[counter].HandleClient + "' as DTparamID Union " + Environment.NewLine;
counter++;
}
query1 = query1.Remove(query1.LastIndexOf("Union"));
UpdateQuery = "Update parameter t Left join " + Environment.NewLine;
UpdateQuery += " ( " + query1 + " ) Temp on" + Environment.NewLine;
UpdateQuery += "t.itemID=Temp.DTparamID" + Environment.NewLine;
UpdateQuery += "set paramvalue=DTvalue,date_logged1=DTdatelogged1,Quality=DTquality,date_logged=DTtimestamp " + Environment.NewLine;
UpdateQuery += "where t.itemID=Temp.DTparamID ";
if (con128.State == ConnectionState.Closed)
con128.Open();
cmd = new OdbcCommand(UpdateQuery, con128);
cmd.ExecuteNonQuery();
if ((con128.State == ConnectionState.Connecting) || (con128.State == ConnectionState.Open))
{
con128.Close();
}
}
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
}
数据更改处理程序每秒钟调用一次,这是由OPC服务器(如计时器)完成的
与其创建大量线程,不如控制和跟踪所创建的内容。例如,使用线程池,或者更好的是使用任务并行库。
第二个想法是,你不应该试图从OOM异常中恢复,你应该提前做好一切,从一开始就避免它。
我非常怀疑是否有人能够在没有源代码的情况下为您提供一个相当普通的问题的"正确"答案。我能做的最好的事情就是给出一些通用的指针:
- 确保您正在处理尽可能多的范围外对象
- 使用线程池对象,因为它只会分配系统可以处理的线程数
- 使用内存探查器查看哪些对象占用的空间最大
现在您已经发布了一些代码:
代码中没有显示您提到的许多线程的创建,但需要注意的是:
OdbcCommand
和OdbcConnection
都是IDisposable
,因此应该被封装到using
中- 考虑使用
string.Format()
而不是串联,以避免创建许多临时字符串。我怀疑这真的会是个问题,但这样会干净一点
除此之外,您的代码看起来不包含任何内存泄漏。