Редактировать: я пытаюсь использовать Области ограниченного выполнения в качестве нового оружия против Abort (). Я все еще провожу тестирование, надеюсь, это сработает. Abort () действительно плохая вещь. Я сообщу позже. . Если у кого-то есть аргументы против CER, пожалуйста, обратите внимание:
У меня проблема с утечкой памяти .NET.
У меня есть довольно сложный проект, потоки в потоках в потоках, что затрудняет его отладку.
Я знаю, Abort()
устарела, но у меня есть причины использовать их:
Мой метод длинный, связанный с сетью. Там нет явной трудоемкой операции, которую я могу поставить флаг внутри. Если я везде поставлю флажки, код будет беспорядочным.
При необходимости нить должна быть прервана сразу, чем раньше, тем лучше. Вся внутренняя работа больше не нужна.
Когда я запускаю программу в обычном режиме, когда потоки заканчивают свою работу и естественным образом умирают один за другим, все в порядке (я запускаю программу 2 года, утечка памяти отсутствует).
Но если я пытаюсь создать новый поток, Start()
и Abort()
их часто (1-2 потока в секунду, чуть быстрее, чем у меня, abort()
), утечка памяти.
И что еще более важно, после завершения операции занимаемая память будет оставаться высокой в течение некоторого времени, например, минут или 10 минут, но в конечном итоге она вернется к нормальному уровню, как будто ничего не произошло.
В режиме отладки я не вижу активных потоков, но память просочилась.
Поэтому для трассировки я использовал профилировщик памяти .NET. Большинство экземпляров, занимающих память, имеют множество byte[]
, на которые ссылается MemoryStream
.
Да, я использую MemoryStream
, но ВСЕ мои MemoryStream
находятся внутри using
блоков, без исключения. Все должно быть в блоке using
правильно.
Насколько я знаю, Thread.Abort()
вызывает исключение для принудительного закрытия, , но, как я подтвердил в режиме отладки, все потоки ожидаемо закрываются . Почему есть еще ссылки? Почему память освобождается через некоторое время? (Но все же намного дольше, чем ситуация, когда я не прекращаю поток и не позволяю ему завершить работу.)
Блоки IMO using
могут гарантировать, что даже ThreadAbortException
, брошенный внутрь Dispose()
, может быть выполнен правильно.
Edit:
![enter image description here](https://i.stack.imgur.com/F5IWM.png)
![enter image description here](https://i.stack.imgur.com/PCiDM.png)
public static byte[] Recover(byte[] png)
{
using (MemoryStream pngStream = new MemoryStream(png))
{
using (System.Drawing.Image image = System.Drawing.Image.FromStream(pngStream))
{
using (MemoryStream bmpStream = new MemoryStream())
{
image.Save(bmpStream, System.Drawing.Imaging.ImageFormat.Bmp);
bmpStream.Seek(0, System.IO.SeekOrigin.Begin);
byte[] BMP = new byte[bmpStream.Length];
bmpStream.Read(BMP, 0, (int)bmpStream.Length);
return BMP;
}
}
}
}
public xxxxMission(byte[] png, Server server, int no) //constructor
{
byte[] bmp = xxxBMP.Recover(png); //png is generated by getBlankBMP();
//....
}