Из того, что я вижу из вашего кода, я бы сказал, что ни Background Background, ни экземпляр класса AsyncUpdateNumber не собираются, поскольку они ссылаются друг на друга, и нет кода, который нарушает эту циклическую ссылку.
Циклическая ссылка создается классом AsyncUpdateNumber, который ссылается на BackgroundWorker и регистрирует событие в BackgroundWorker, создавая ссылку на экземпляр класса AsyncUpdateNumber.
Итак, что вы можете сделать ... рассмотрите возможность использования одного из следующих параметров вместо BackgroundWorker:
- Использовать тему.
- Использовать BeginInvoke.
- Используйте ThreadPool.
Образец 1:
var thread = new Thread(new ParameterizedThreadStart((v) => { /* do stuff */ }));
thread.Start(value);
Образец 2:
var func = new Action<int>(v => { /* do stuff */ });
func.BeginInvoke(value, null, null);
Образец 3:
var threadProc = new Action<object>(v => { /* do stuff - note v is of tyoe object */ });
ThreadPool.QueueUserWorkItem(new WaitCallback(threadProc));
Edit:
Чтобы ответить на ваш вопрос из исходного поста: метод, выполняющий поток, всегда работает до его завершения, независимо от того, завершает ли метод, объявивший его, или нет. Даже вышеописанные анонимные методы будут работать до тех пор, пока не будут завершены. Применяемая здесь концепция называется замыканием (AFAIK), в случае анонимных методов она даже сохраняет все ссылочные переменные живыми, даже если они не объявлены в самом методе.
Однако ваш класс является ярким примером циклической ссылки, которая будет восстановлена только после завершения процесса приложения. Это одна из этих более тонких вещей в .NET, которая - даже в управляемой системе - может вызвать утечки памяти ... события создают сильные ссылки .
Хотя в случае одного звонка это не вызывает никаких проблем, если вы нажмете несколько звонков, это действительно может стать проблемой.