2011-06-03 23 views
-1

我已经开发了C#应用程序创建的线程数,一段时间后经过创建一个新的Thread.any的想法来处理这个异常时,它抛出异常的System.OutOfMemoryException的。没有使用try-catch。如何增加内存空间或如何释放内存中的线程。这个东西处理速度非常快。处理异常如不为System.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服务器此做过类似计时器

+0

期待帮助?发布一些代码... – Stefan 2011-06-03 07:39:48

+0

你不应该问一个问题中的多个问题。考虑为你的第二段创建另一个问题 - 这将使它更容易找到。 – ChrisWue 2011-06-03 07:40:04

+0

主题在哪里? – 2011-06-03 09:30:27

回答

4

而不是创建线程的数量庞大每秒,你应该保持你所创造的控制和轨道。例如,使用一个线程池,或者甚至更好的任务并行库。

另一个想法是,你不应该尝试从OOM异常恢复,你应该做的一切前期,以避免它摆在首位。

+0

+1。我以前见过这种类型的问题,并且正如你写的那样,解决方案是使用可用于每个.NET进程的线程池(例如,通过任务库,异步方法等) – paercebal 2011-06-03 07:54:47

1

我非常怀疑任何人都可以给你“正确”的答案,数额是多少,有没有源代码一个非常通用的问题。我能做的最好的是给出几个通用指针:

  • 请确保您正在处理尽可能多的超出范围的对象。
  • 使用线程池对象,因为它只会分配尽可能多的线程,因为系统可以处理。
  • 使用内存分析器查看占用最多空间的对象。
0

现在,您已经发布了一些代码:

代码不会在任何地方展示你提到但有几件事情要注意多线程的创建:

  1. 两个OdbcCommandOdbcConnection分别为IDisposable,因此应将其包装为using以确保任何(未拆分的)资源已正确释放。
  2. 考虑使用string.Format()而不是串联来避免创建许多临时字符串。我怀疑这真的会成为一个问题,但是这样会更清洁一些。

除此之外,你的代码看起来并不像它包含任何内存泄漏。

+0

请注意,我已经从创建大量线程的看到了内存不足的异常... – paercebal 2011-06-03 07:52:45

+0

一个trhead占用最少的1 MB ...创建太多是一个很好的理由福尔OOM – 2011-06-03 09:29:13

+0

我以为,最小值为堆栈+ 64KB一些。网络和操作系统开销来跟踪线程(http://blogs.msdn.com/b/oldnewthing/archive/2005/07/29/444912.aspx)?哪一个没有接近1MB的地方。虽然即使OOM没有给你带来大量的线程,CPU也会出现抖动。 – 2011-06-03 09:42:43