Это упрощенный код, просто иллюстрирующий проблему, которую я пытаюсь решить (не скомпилировал, поэтому, пожалуйста, игнорируйте любые синтаксические ошибки). Предположим, у меня есть ProducerProxy как:Правильно избавляйтесь от производителя событий от другой нити
public class ProducerProxy : IDisposable {
public event EventHandler<EventArgs> NotificationEvent;
private volatile bool itsKeepProducing = true;
public DoStuff() {
Task.Factory.StartNew(() => {
while (itsKeepProducing) {
RaiseNotificationEvent();
Thread.Sleep(100);
}
}
}
public void Dispose() {
itsKeepProducing = false;
DestroySomeStuff();
}
}
Пусть теперь у меня есть класс, который использует этот ProducerProxy:
public class Consumer : IDisposable {
private ProducerProxy itsProducerProxy;
public void Consumer() {
itsProducerProxy = new ProducerProxy();
itsProducerProxy.NotificationEvent += OnNotificationEvent;
}
public void Start() {
itsProducerProxy.DoStuff();
}
public void OnNotificationEvent(object sender, EventArgs args) {
DealWithNotification(args); //this could take some time maybe 1-2 seconds
}
public void Dispose() {
//how do I dispose of the producer here?
//I can't just do the following because notifications might still be processing in OnNotification event:
if (itsProducerProxy != null) {
itsProducerProxy.NotificationEvent -= OnNotificationEvent;
itsProducerProxy.Dispose();
itsProducerProxy = null;
}
}
Так что мой вариант использования (да, это должно быть сделано с помощью try/catch
или с помощью using
но что отвлекает от вопроса - просто иллюстрирующей точку)
var consumer = new Consumer();
consumer.Start();
... //do some stuff
consumer.Dispose();
что такое правильная/надлежащей поточно-реализация для Consumer.Dispose()
? или, возможно, для Producer.Dispose()
?
'// это может занять некоторое время, может быть, 1-2 секунды, может ли это понять, что во время процесса может произойти утечка? Может ли он проверить CancellationToken, выполняя свою работу, понимая, когда IsCancellationRequested истинна, объект удален и пришло время прекратить работу? – Will
@ Будет, возможно, удаление может происходить во время обработки события. Не стесняйтесь публиковать решение, используя CancellationToken. – Denis
Наверное, самым безопасным будет просто убедиться, что ваш «EventArgs» несет в нем все необходимое состояние. Тогда не имеет значения, происходит ли удаление промежуточной обработки. На самом деле это зависит от того, насколько вы полагаетесь на «ProducerProxy» внутри вашего обработчика. –