Ключевой частью этого является не первая часть сообщения об ошибке, а последняя часть:
уже утилизировано.
using(var threadLifeTime = AutofacDependencyResolver.Current.ApplicationContainer.BeginLifetimeScope())
{
_lifeTimeScopeChild = threadLifeTime;
Thread t = new Thread(new ParameterizedThreadStart(MySeparateThread));
t.Start(id);
}
threadLifeTime
создается в объявлении вашего блока using
. В конце этого блока он утилизируется. Это единственная цель блока using
. В нем заложено предположение, что в этот момент можно расположить объект. Вы закончили с этим.
Вы также создаете отдельный поток и передаете ему threadLifeTime
. Часть кода, где это происходит, не показана, но это то, что происходит. Возможно, вы не передаете его явно, но на него ссылаются где-то в ParameterizedThreadStart
и MySeparateThread
.
Этот поток продолжает выполняться отдельно от метода, который первоначально вызвал его. Так что сразу после того, как вы сдадите этот предмет, он утилизируется Что бы ни делал этот поток, он пытается сделать это с удаленным объектом. Это ошибка.
Обычно в конце блока using
переменная (threadLifeTime
) выходит из области видимости. Там не будет никаких ссылок на него, поэтому не имеет значения, если он будет утилизирован. Но теперь есть ссылка на это, что является проблемой, поскольку это ссылка на что-то, что было уничтожено.
Краткосрочное решение - не создавать отдельную ветку. Если есть правильный ответ на этот вопрос, который включает в себя многопоточность, это более сложно и выходит за рамки этого ответа. Хорошее практическое правило - сначала заставить код работать без многопоточности, а затем добавить его, если вам это нужно. В противном случае вы не знаете, является ли проблема многопоточностью или чем-то еще.
Другая проблема заключается в следующем:
_lifeTimeScopeChild = threadLifeTime;
Это указывает, что он не только передается в какой-то другой поток, но также присваивается полю внутри класса. Это тоже проблема по той же причине. Ссылка, которую вы назначаете этому полю, будет существовать даже после удаления объекта. Если что-то попытается использовать _lifeTimeScopeChild
после того, как этот блок using
завершится, он получит ту же ошибку.
Вопрос, на который нужно ответить: «Нужен ли этот объект моему методу или моему классу нужен этот объект?»
Если ваш метод нуждается в этом, объявите и используйте его в методе, но не позволяйте ссылкам на него, которые вы не можете контролировать, «убежать» из метода. Если вы избавитесь от этого, то сломаете все, что пытается его использовать. И если вы не избавитесь от него, тогда, ну, он не избавится, когда должен.
Если вашему классу это нужно, подумайте о том, чтобы создать его при создании класса или использовать ленивый экземпляр для его создания, когда он вам нужен. (Я бы начал с первого.) Затем заставьте ваш класс реализовать IDisposable
, и когда ваш класс будет утилизирован, тогда вы избавитесь от любых доступных ресурсов, используемых вашим классом.