2015-10-27 2 views
0

Статический вопрос:Non-Static и статический метод и класс памяти распределение

В моей C# приложения на основе я должен использовать некоторый статический метод из статического класса. Это часть моего кода:

 //Timer Event (interval: 100ms) 
     private void OnTimedEvent2(object source, ElapsedEventArgs e) 
     { 
      try 
      { 
       //... 

       DataUpdaterClass.Update("SomeString"); 

       //... 
      } 

      catch (Exception ex) 
      { 
       //... 
      } 

Мой вопрос, если я называю метод Update в каждом TimerTick, он будет выделять память каждый раз, или только один раз?

Нестатические вопрос:

же Timer но не-статический метод.

 static IPEndPoint MyIPEndPoint = new IPEndPoint(IPAddress.Parse("127.0.0.1"), 9999); 
     static Socket MySocket = null; 

     ////Timer Event (interval: 100ms) 
     private void OnTimedEvent2(object source, ElapsedEventArgs e) 
     { 
      try 
      { 
       if (MySocket == null) 
       { 
        MySocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); 
        MySocket.Connect(MyIPEndPoint); 
       } 

       //... 
      } 

      catch (Exception ex) 
      { 
       MySocket.Dispose(); 
       MySocket = null; 
      } 
     } 

Мой второй вопрос, если я программа выдаст ошибку, то будет моим Socket выпущен и не будет использовать любую память в будущем?

Большое спасибо.

EDIT:

Спасибо за ваши ответы. Я чувствую, что мне нужно добавить дополнительную информацию для вас.

Мое приложение - это служба Windows, которая собирает данные с промышленных устройств с нашего завода по поводу веса продукта. Поэтому он должен работать непрерывно. Теперь я проверяю используемую память моей службой, и я вижу, что она всегда больше. Он растет очень медленно, и я вижу, что GC делает свою работу, но используемая память все еще растет. Я отправляю свое полное событие Timer и метод Update также. Я надеюсь, что вы можете мне помочь.

Имена классов, переменных и методов венгерского языка, я надеюсь, что это не вызовет проблем. событие

Таймера:

 static string Adat1 =static string IP1 = Convert.ToString(_3DESDekodoloClass.Decrypt(ConfigurationManager.AppSettings["merleg_1_IP"])); 
     static int Port1 =Convert.ToInt32(_3DESDekodoloClass.Decrypt(ConfigurationManager.AppSettings["merleg_1_Port"])); 
     static int Olvasott1 = 0; 
     IPEndPoint Vegpont1 = new IPEndPoint(IPAddress.Parse(IP1), Port1); 
     Socket Merleg1 = null; 
     static byte[] Buffer1 = new byte[1024]; 

     //Starts in the OnStart() event. 
     private void OnTimedEvent1(object source, ElapsedEventArgs e) 
     { 
      try 
      { 
       if (Merleg1 == null) 
       { 
        Merleg1 = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); 
        Merleg1.Connect(Vegpont1); 
       } 

       Olvasott1 = Merleg1.Receive(Buffer1); 
       Adat1 = Encoding.ASCII.GetString(Buffer1, 0, Olvasott1); 
       AdafeltoltoClass.Merleg_1_adatfeltolto(Adat1); 
      } 

      finally 
      { 
       if (Merleg1 != null) 
       { 
        Merleg1.Dispose(); 
       } 

       Merleg1 = null; 
      } 
     } 

И это мой Update метод:

 static AnritsuDataCollector fo_osztaly = new AnritsuDataCollector(); 

     static SqlDataAdapter sda_1 = new SqlDataAdapter(); 
     static SqlDataAdapter sda_2 = new SqlDataAdapter(); 

     static SqlDataAdapter sda_gauss_1 = new SqlDataAdapter(); 
     static SqlDataAdapter sda_gauss_2 = new SqlDataAdapter(); 

     //Adatok kinyerése a config fájlból dekódolás után. 
     static string data_source = _3DESDekodoloClass.Decrypt(ConfigurationManager.AppSettings["data_source"]); 
     static string initial_catalog = _3DESDekodoloClass.Decrypt(ConfigurationManager.AppSettings["initial_catalog"]); 
     static string user_id = _3DESDekodoloClass.Decrypt(ConfigurationManager.AppSettings["user_id"]); 
     static string password = _3DESDekodoloClass.Decrypt(ConfigurationManager.AppSettings["password"]); 

     static string ProductId1 = ""; 
     static string RankCode1 = ""; 
     static string Suly1 = ""; 

     static string ProductId2 = ""; 
     static string RankCode2 = ""; 
     static string Suly2 = ""; 

     internal static void Merleg_1_adatfeltolto(string beerkezo) 
     { 
      try 
      { 
       //Az "con" SQL kapcsolat Pool-ba tétele. 
       using (SqlConnection con = new SqlConnection(@"Data Source=" + data_source + ";Initial Catalog=" + initial_catalog + ";User ID=" + user_id + ";Password=" + password + ";")) 
       { 
        //A kapcsolat megnyitása. 
        con.Open(); 

        ProductId1 = beerkezo.Substring(4, 2); 
        RankCode1 = beerkezo.Substring(6, 1); 
        Suly1 = beerkezo.Substring(7, 5); 

        //Ha a suly tartalmaz szóközt. 
        if (Suly1.Contains(' ')) 
        { 
         Suly1 = "00.00"; 
        } 

        //SQL parancs az adatok feltöltéséhez. 
        using (sda_1.InsertCommand = new SqlCommand("INSERT INTO meresek (product_id, rank_code, merleg, suly, ido) VALUES (@product_id, @rank_code, @merleg, @suly, @ido)", con)) 
        { 

         sda_1.InsertCommand.Parameters.Add("@product_id", SqlDbType.Int).Value = Convert.ToInt32(ProductId1); 
         sda_1.InsertCommand.Parameters.Add("@rank_code", SqlDbType.VarChar).Value = Convert.ToString(RankCode1); 
         sda_1.InsertCommand.Parameters.Add("@merleg", SqlDbType.Int).Value = 1; 
         sda_1.InsertCommand.Parameters.Add("@suly", SqlDbType.Float).Value = Convert.ToDouble(Suly1.Replace('.', ',')); 
         sda_1.InsertCommand.Parameters.Add("@ido", SqlDbType.DateTime).Value = DateTime.Now; 

         //Az SQL utasítás elküldése a szervernek 
         sda_1.InsertCommand.ExecuteNonQuery(); 
        } 

        using (sda_gauss_1.UpdateCommand = new SqlCommand("IF EXISTS(SELECT ROUND(suly,0) FROM gauss_statisztika_merleg_1 WHERE ROUND(suly,0) = @suly AND product_id = @product_id) BEGIN UPDATE gauss_statisztika_merleg_1 SET darab = darab + 1, utolso_meres = @utolso_meres WHERE ROUND(suly,0) = @suly AND product_id = @product_id END ELSE BEGIN INSERT INTO gauss_statisztika_merleg_1 VALUES(@product_id, @suly, 1, 1, @utolso_meres) END", con)) 
        { 
         sda_gauss_1.UpdateCommand.Parameters.Add("@suly", SqlDbType.Float).Value = Math.Round(Convert.ToDouble(Suly1.Replace('.', ','))); 
         sda_gauss_1.UpdateCommand.Parameters.Add("@product_id", SqlDbType.Int).Value = Convert.ToInt32(ProductId1); 
         sda_gauss_1.UpdateCommand.Parameters.Add("@utolso_meres", SqlDbType.DateTime).Value = DateTime.Now; 

         sda_gauss_1.UpdateCommand.ExecuteNonQuery(); 
        } 
       } 
      } 

      catch (Exception ex) 
      { 
       fo_osztaly.Eventlog.WriteEntry(ex.Message); 
      } 
     } 
+0

'System.Net.Sockets.Socket' реализует IDisposable, используйте' using' –

+0

@ Avsenev-Slava MySocket объявлен вне функции и используется каждый раз, когда вызывается функция: это не сценарий для 'use' –

+0

@GianPaolo. В любом случае, это нехороший подход, а не потокобезопасный. Поэтому я бы подумал об этом аспекте, в отличие от выделения памяти здесь. –

ответ

0

вопрос № 1: вы ваш OnTimedEvent2 вы вызываете статический метод: компилятор не будет выделять какие-либо памяти для этого просто введите код для вызова метода. Что входит в этот метод, это еще одна пара рукавов: если он выделяет память, он будет для каждого вызова. Но на самом деле это зависит от реализации DataUpdaterClass.Update.

вопрос # 2: установка переменной MySocket на нуль и, следовательно, удаление всей ссылки на выделенный сокет, позволит сборщику мусора освободить память. GC освободит его в соответствии с его собственной логикой. Итак, вы можете считать, что память, используемая выделенным сокетом, будет выпущена.

В качестве примечания стороны: не фокусируйтесь на управлении памятью так много. .NET реализовал Garbage Collection, чтобы освободить разработчика от проблем управления памятью. И я никогда не нашел случая, когда GC не выполнял свою работу должным образом.

Есть случаи, когда вы должны заботиться о том, сколько памяти ваша программа выделяет и не отпуская, ваши два случая среди них не

1

Статический вопрос: Призвание уже подписался обработчиков не будет вызывать память распределение. Код уже находится в памяти. Исполнение кода может инициировать распределение памяти.

Нестатический вопрос: Вы не можете гарантировать, что объект будет удален из памяти - так что ответ может быть. У вашего образца есть ошибка - вы должны изменить «catch» на «finaly» и проверить, что MySocket не имеет значения null перед удалением.

Прочее: Основываясь на ваших вопросах, я не думаю, что имеет смысл уделять большое внимание эффективному использованию памяти. Это управляемый язык, и большинство элементов управления памятью выполняется самим .NET Framework

Смежные вопросы