以相反的顺序处理对象? [英] Dispose of objects in reverse order of creation?

查看:102
本文介绍了以相反的顺序处理对象?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在编写的代码中遇到一个反复出现的问题:修改某些全局值(我将使用注册表值作为示例),然后尝试将修改恢复为原始状态。

I face a recurring problem in the code I write: modifying some global value (I'll use a registry value just as an example) and then trying to revert the modifications to original state.

我想我会尝试使用IDisposable解决此问题。创建对象后,该对象将读取注册表值,将其存储在本地,然后对其进行修改。销毁后,它将还原设置。会使用类似这样的东西:

I thought I'd try to use IDisposable to solve this problem. When created, the object would read the registry value, store it locally, and then modify it. When destroyed, it would revert the setting. It would be used something like this:

using(RegistryModification mod = new RegistryModification("HKCR\SomeValue", 42))
{
    // reg value now modified to 42, do stuff
} // Object gets disposed, which contains code to revert back the setting

如果只进行了1次修改,则应该很好用。但是,如果进行了多次修改,或者调用者未使用使用结构创建对象,则可以看到出现了麻烦。

Should work great, if only 1 modification is ever made. But if multiple modifications are made, or the caller does not create the objects with the 'using' construct, I can see trouble occuring.

public void Foo()
{
    // assume HKCR\SomeValue starts as '13'

    // First object reads HKCR\SomeValue and stores '13', then modifies to 42
    RegistryModification mod1 = new RegistryModification("HKCR\SomeValue", 42); 

    // Next object reads HKCR\SomeValue and stores '42', then modifies to 12
    RegistryModification mod2 = new RegistryModification("HKCR\SomeValue", 12);

}
// objects are destroyed. But if mod1 was destroyed first, followed by mod2,
// the reg value is set to 42 and not 13. Bad!!!

如果调用者手动处理对象,则问题会恶化。这使我认为我的方法很简单。

The problem worsens if a caller manually disposes the object. This leads me to think my approach is, simply, flawed.

是否存在某种可以接受的模式来解决此问题?我当时想向类中添加静态堆栈可能会有所帮助。

Is there some sort of accepted pattern to solve this problem? I was thinking adding a static stack to the class might help.

对象销毁的顺序是否得到保证?我以为我会尝试使用IDisposable,但对其他解决方案却无所适从。

Is the order that objects are destroyed guaranteed in any way? I thought I'd try with IDisposable, but am all ears for other solutions.

推荐答案

IDisposable不能保证您所描述的回滚是这种回滚。 Dispose()方法并非用于此目的,而是负责释放对象拥有的本机资源(网络连接,文件等)

IDisposable does not guarante a rollback in this fashion what you are describing is a rollback. The Dispose() method is not meant for that purpose rather it is responsible for the releasing of native resources that the object holds (network connections, files etc)

恢复状态可以这样做

public void Foo(SomeObjectType theObject)
{
    int initialValue = theObject.SomeProperty;
    theObject.SomeProperty = 25;
    Console.Out.WriteLine("Property is:" + theObject.SomeProperty);

    // reset object.
    theObject.SomeProperty = initialValue;
    Console.Out.WriteLine("Property oringinal value is:" + theObject.SomeProperty);
}

请记住,仅因为资源被处置并不会逆转已执行的操作使用它,如果您处理数据库连接并不会撤消对其执行的工作,只会破坏该对象。

Remember just because a resource is disposed of it does not reverse actions that were performed using it, if you dispose of a database connection it does not undo work carried out with it, just destroys the object.

除非您使用回滚代码覆盖Dispose(),这是对该方法的滥用,那么它将不会提取您的值,即您作为程序员的责任感。我之所以说它是对dispose方法的滥用,是因为.net文档对 Dispose()

Unless you override Dispose() with rollback code, which is a misuse of that method, then it will not pull out your values, that is your resonsibility as the programmer. The reason I say it is a misuse of the dispose method is because the .net documentation states the following for Dispose()


使用此方法关闭或释放非托管资源,例如文件,
流以及由实现该接口的
的类的实例持有的句柄。按照惯例,此方法用于与释放对象所拥有的资源或准备
对象以供重用相关的所有任务

Use this method to close or release unmanaged resources such as files, streams, and handles held by an instance of the class that implements this interface. By convention, this method is used for all tasks associated with freeing resources held by an object, or preparing an object for reuse.

这通常意味着释放例如重量级东西的句柄(例如某些GDI资源)。必须释放本机资源,或有时将本机资源置于某种状态,以避免内存泄漏或访问的不良后果。在这种情况下,很容易地说,也许您应该在Dispose方法中将注册表重新设置为以前的状态,但是我认为这不是dispose方法的意图。目的是释放资源并将其放回可再次使用的状态。您想要做的就是重置一个值(本质上是另一个设置操作),以自定义处置方法进行工作意味着您稍后还会在不同的上下文中缩短重用机会。

This generally means for example freeing handles to heavyweight stuff ( say for example some GDI resource). Native resources must be freed or sometimes placed into a certain state to avoid memory leaks or unwanted consequences of access. It is easy to say in this case that perhaps in your Dispose method you should set your registry back to the state it was before, but It is my view this is not the intent of the dispose method. The intent is to release resource and put them back into a state where they can be used again. What you want to do is reset a value (which is essentially another set operation), Doing that work in a custom dispose method means you also shorted reuse opportunities later in different contexts.

我的意思是,完成修改后,必须编写显式代码以将对象设置回其初始状态。您可能可以将其存储在数据结构(例如堆栈)中,如果有多个操作,则可以读回值,或者仅对一个操作使用上述简单方法即可。

What I am saying is that when you have finished modifying you must write explicit code to set the objects back to their initial state. You could probably store this in a data structure (say a stack) and read back the values if there were multiple operations, or just use a simple method like above for one operation.

这篇关于以相反的顺序处理对象?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆