запускаю поток, в нем открывается форма с помощью Application.Run(frm)
через некоторое время основной поток завершает его с помощью thread.Abort() проблема в том, что иногда (редко, но все же) возникает
System.Threading.ThreadAbortException: Thread was being aborted.
стэктрэйсы разные, но они все содержат события прорисовки контролов, по-видимому, этой формы. если я перехвачу событие этого дополнительного потока
Application.ThreadException += (s, e) => { };
т.е. просто заглушу его ошибки (в нем нет ничего критичного, это информационное окно), не останутся ли ссылки внутри этого потока и не останется ли он в памяти?
в качестве примера можно рассмотреть такой код:
void runThread()
{
//запускаем поток
var t = new Thread(showForm);
t.Start();
//что-то делаем
Thread.Sleep(10000);
// грубо завершаем дочерний поток
t.Abort();
}
/// <summary>
/// ф-ция дочернего потока
/// </summary>
void showForm()
{
Application.ThreadException += (s, e) => { }; // достаточно ли этого чтобы тихо закрыть поток?
Application.Run(new myForm()); // на этой форме может происходить что угодно в плане отображения.
// данными не оперируем, только визульные фишечки. допустим, гифка крутится
}
Никаких лишних ссылок не останется, сборщик мусора все приберет. Если только вы сами не наоткрываете неуправляемых ресурсов.
Тем не менее, я бы не рекомендовал решать эту задачу через Thread.Abort. Правильнее останавливать дополнительный UI-поток через Application.ExitThread или закрывая главную форму.
К сожалению, оба действия можно делать только в том потоке, где эта форма была создана. Для того, чтобы передать сигнал на закрытие в другой поток, проще всего использовать токен отмены (CancellationToken, .NET 4.0+) и контекст синхронизации (SynchronizationContext).
Получается примерно так:
void RunThread() {
var cts = new CancellationTokenSource();
var t = new Thread(ShowForm);
t.Start(cts.Token);
//что-то делаем
Thread.Sleep(10000);
// аккуратно завершаем дочерний поток
cts.Cancel();
t.Join();
}
void ShowForm(object obj)
{
var token = (CancellationToken)obj;
var form = new MyForm(); // В этот момент устанавливается контекст синхронизации потока
var ctx = SynchronizationContext.Current; // В этот момент контекст синхронизации должен быть уже установлен
using (token.Register(() => {
ctx.Post(_ => Application.ExitThread(), null); // Нельзя использовать Send - в этот момент мы можем уже выходить из `Application.Run` по какой-то причине
})) { // Нельзя использовать useSynchronizationContext - он внутри использует Send
Application.Run(form);
}
}
Современные решения для бизнеса: как облачные и виртуальные технологии меняют рынок
Виртуальный выделенный сервер (VDS) становится отличным выбором
Приложение должно выполнить команды по созданию mailbox напримерЗапускаться в локальной сетке, но не с машины где стоит сам Exchange
Я пытаюсь получить Exif из JPG и CR2 файлов
Подскажите, есть ли способ сгенерировать GUID код, с фигурными скобками?