简体   繁体   English

仅在变量为零时执行处置

[英]Execute Dispose only if variable is zero

Rough context: messaging system, Communicator sends messages (increases field _messagesInTransmission ), receives ACK or NAK on another thread (decreases _messagesInTransmission ). 粗糙的上下文:消息传递系统, Communicator发送消息(增加字段_messagesInTransmission ),在另一个线程上接收ACK或NAK(减少_messagesInTransmission )。

If an instance of Communicator is disposed it should stop its underlying transport instance as soon as _messagesInTransmission hits zero the next time. 如果释放了Communicator实例,则下次_messagesInTransmission达到零时,应停止其基础传输实例。

How to implement this in a thread-safe way? 如何以线程安全的方式实现这一点?

public void Dispose()
{
    _state = State.Stopping; // immediately change state in order to prevent additional messages to be sent

    // TODO: wait for _messagesInTransmission to become zero
}

Does the .NET framework support me with this task? .NET框架是否支持我执行此任务?


A simple solution would be a while(_mIT != 0) loop and some Thread.Sleep, however, I want to write more appealing code if possible. 一个简单的解决方案是while(_mIT!= 0)循环和一些Thread.Sleep,但是,如果可能的话,我想编写更具吸引力的代码。

You really don't want to do this on Dispose() . 您真的不想在Dispose()上执行此操作。

Consider a situation where your receiving application crashes and never ACK/NACK's one of the messages. 考虑一种情况,在这种情况下,您的接收应用程序崩溃,并且永远不会出现ACK / NACK消息之一。 You'll never receive enough responses to zero the counter, and when the dispose is called, possibly during GC or a using(...){...} block, it's going to hang indefinitely. 您将永远不会收到足够的响应以使计数器归零,并且当调用dispose时,可能在GC或using(...){...}块期间,它将无限期地挂起。

I'd suggest moving this functionality to another method which is called OnStop() . 我建议将此功能移至另一个称为OnStop()

And just keep your Dispose() method for cleaning up resources, closing connections etc... 只需保留您的Dispose()方法即可清理资源,关闭连接等。

How vital is it that those messages are sent? 发送这些消息有多重要? Generally, you should have some kind of Stop() method on your class to do what you are looking for. 通常,您应该在类上具有某种Stop()方法以执行所需的操作。 Doing this kind of action in the Dispose method is a little dangerous because Dispose methods shouldn't have the potential to throw errors or hang. 在Dispose方法中执行这种操作有点危险,因为Dispose方法不应该引发错误或挂起。

Also, make sure your worker thread is created with IsBackground set to true. 另外,请确保在IsBackground设置为true的情况下创建了工作线程。 That way, when your application closes, it is certain to complete as well. 这样,当您的应用程序关闭时,它肯定也会完成。

The "thread safe" way to do it (and is how things like FileStream handle it) is to have a Flush() method that is blocking that writes out all the pending writes. 做到这一点的“线程安全”方法(以及FileStream处理方式)是具有一个Flush()方法,该方法会阻塞所有未完成的写操作。 Once you have that you just need to have Flush() be called inside the Dispose() method. 一旦有了,就只需要在Dispose()方法中调用Flush()

Now this will cause Dispose() to block, but you know what? 现在,这将导致Dispose()阻塞,但是您知道吗? We want dispose to block! 我们要处置封锁! If you do not block on dispose while work is still being done the last reference to the object could be released (very likely to happen inside a using block) and your object will be eligible for garbage collection before it is done processing. 如果在完成工作时不阻止处置,则可以释放对该对象的最后一个引用(很可能发生在using块内),并且在处理完对象之前,您的对象将可以进行垃圾回收。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM