Как удалять файлы в памяти, которую оставляет MemoryStream, с C#?

оказывается, что я использую MemoryStream чтобы читать файл с ReadToEnd следующей формы:

IEnumerable<uint> uids = Client.Search(SearchCondition.Unseen());
IEnumerable<MailMessage> messages = Client.GetMessages(uids, FetchOptions.Normal);
 foreach (MailMessage msg in messages){

  foreach (Attachment atc in msg.Attachments){
     byte[] allBytes = new byte[msg.Attachments[0].ContentStream.Length];
     int bytesRead = msg.Attachments[0].ContentStream.Read(allBytes, 0, (int)msg.Attachments[0].ContentStream.Length);

     MemoryStream memory = new MemoryStream(allBytes);                          
     System.IO.StreamReader archivoXML = new System.IO.StreamReader(memory);
     memory.Close();
     String archivoXML_texto = archivoXML.ReadToEnd();
     archivoXML.Close();
  }

}

Ввиду этого, у меня есть беспокойство, которое в памяти могло бы оставаться несколько файлов мусор. Если бы это было так, мне хотелось бы знать, как удалять или отлаживать память этих файлов, прочитав их, где они получены с MemoryStream.

Наблюдение: я читаю добавление с почты используя протокол IMAP, и не с сохраняемого маршрута.

Наблюдение 2: использовав это преподавание, он читает мне контент, а у меня есть она, переменная archivoXML_texto хранит пустоту:

 int bytesRead = msg.Attachments[0].ContentStream.Read(allBytes, 0, (int)msg.Attachments[0].ContentStream.Length);
0
задан 14.03.2017, 23:21
0 ответов

C# использует управляемого автоматического памяти. Он реализован эту пересборщиком мусора (Гарбахе Кольектор).

Для твоего случая не является рекомендуемым использовать пересборщика мусора, но если ты все же принимаешь решение назвать это, ты можешь использовать методы класса System.GC

GC.Collect();
GC.WaitForPendingFinalizers();

Классы MemoryStream и StreamReader они осуществляют интерфейс IDisposable что содержат метод Dispose что стоит освобождать ресурсы и быть имеющим право быть избранным из-за пересборщика мусора. Следовательно ты можешь объявлять их во внутри блока using гарантируя, что метод Dispose он будет призван или блокtry catch finally

byte[] allBytes = new byte[msg.Attachments[0].ContentStream.Length];   

using( MemoryStream memory = new MemoryStream(allBytes),
       StreamReader archivoXML = new StreamReader(memory))
{ 
   String archivoXML_texto = archivoXML.ReadToEnd();
}
1
ответ дан 03.12.2019, 17:56
  • 1
    и потому что не serí в reconmendable использовать пересборщик мусора??? –  29.12.2016, 23:53
  • 2
    @Danilo, Из-за которого ты используешь только có я говорю управляемый. –  30.12.2016, 00:54
  • 3
    тогда, лучшее состояло бы в том, чтобы использовать вещь así??? using (MemoryStream memory = new MemoryStream (allBytes)) { StreamReader archivoXML = new StreamReader (memory); archivoXML_texto = archivoXML.ReadToEnd (); archivoXML.Close (); memory. Dispose (); } –  30.12.2016, 02:33

Относительно твоего первичного вопроса, в .NET, обычно нет необходимости беспокоиться несмотря на то, что возвращать память. .NET включи recolectador мусора, который автоматически и периодически обнаруживает структуры в памяти, в которой программа уже не нуждается и собирает их.

Так что, если только ты не делаешь что-то очень передовым, ты не беспокоился о том, чтобы вернуть потерянную память. Это будет сделано автоматически.


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

  1. Всегда ты был бы должен использовать классы Stream в блоках using для того, чтобы Dispose работайте автоматически, еще в случае, если lanze исключение.
  2. Несмотря на то, что ты прочитаешь каждый attachment в цикле, только ты ссылаешься на первый attachment со следующим выражением (он замечает индекс [0]): msg.Attachments[0].ContentStream.Length.
  3. (эта точка уже не применяется с тех пор, как editastes код в твоем вопросе) самая Серьезная проблема - что: никогда ты не читаешь контент attachments! Когда ты будешь верить в договоренность allBytes (byte[] allBytes = new byte[msg.Attachments[0].ContentStream.Length];), единственное, что ты делаешь, состоит в том, чтобы давать ему длину, эквивалентную контенту attachment, но контент в себе это чистые нули.
  4. Нет необходимости использовать одну посредническая договоренность байт. Ты можешь происходить ContentStream прямо в StreamReader.

Со всеми этими точками в разуме, код должен бы быть похожим скорее на следующее:

foreach (Attachment atc in msg.Attachments)
{
    using (var streamReader = new StreamReader(atc.ContentStream))
    {
        String archivoXML_texto = streamReader.ReadToEnd();
        // hacer algo con la cadena...
    }
}
0
ответ дан 03.12.2019, 17:56
  • 1
    Я это попробовал, но стоимость archivoXML_texto, который он получает, пусто. –  30.12.2016, 03:18
  • 2
    И có я говорю настоящий, что ты имеешь, ¿ ты это протестировал? –  30.12.2016, 03:20
  • 3
    using (MemoryStream memory = new MemoryStream (allBytes)) { StreamReader archivoXML = new StreamReader (memory); archivoXML_texto = archivoXML.ReadToEnd (); archivoXML.Close (); memory. Dispose (); } больше, что я прокомментировал. Это проблема, которая не может прочитать, этой формы. Немного как.ContentStream. Рид. Издайте вопрос используя эту же самую intrucció n –  30.12.2016, 03:30
  • 4
    Я подозреваю, что не copiastes хорошо có я говорю, что я поместил тебя, или он agregastes немного. Потому что это patró n правильный и это довольно просто. Если ты хочешь, чтобы он старался понимать лучше проблему, включи в твоем вопросе có я говорю точно, что ты используешь, что segú n ты говоришь, что он способствует тому, чтобы он закончился цепью vací в. –  30.12.2016, 03:35
  • 5
    Но глаз, что вопрос está изменяя intenció n оригинал относительно управления памяти... –  30.12.2016, 03:37