Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/293.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/search/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 关于weakreference的问题_C# - Fatal编程技术网

C# 关于weakreference的问题

C# 关于weakreference的问题,c#,C#,我有一个关于weakreference的问题 我现在正在编写一个资源管理器,它必须保留对已创建纹理对象的引用。我有一本字典,像: Dictionary<uint, WeakReference> 我遇到的问题是,后面的部分: if (result.IsAlive) 从未到达,因为仍有对资源的剩余引用 问题是,我只有一个相关资源的引用,它会像这样释放自己: resource.free(); // calls internally its owner (i.e. ResMgr) res

我有一个关于weakreference的问题

我现在正在编写一个资源管理器,它必须保留对已创建纹理对象的引用。我有一本字典,像:

Dictionary<uint, WeakReference>
我遇到的问题是,后面的部分:

if (result.IsAlive)
从未到达,因为仍有对资源的剩余引用

问题是,我只有一个相关资源的引用,它会像这样释放自己:

resource.free(); // calls internally its owner (i.e. ResMgr)
resource = null;
我猜剩余的引用应该是资源变量,但我不能将其设置为null,因为我必须首先调用free。相当困难

我想要实现的是一个资源管理器,它保留对其拥有的资源的引用,并且只有在没有引用的情况下才释放它们,以避免搞砸某些事情

你知道我该如何以干净的方式解决这个问题吗

PS:有没有办法以某种方式获得引用计数

提前谢谢


如果result.IsAlive为false,则result.Target将为null

您可能希望查看终结器和/或,它们可能会帮助您找到解决方案。

我建议您查看终结器或引用计数。弱引用从未被嵌入到缓存系统中。
.NET中没有引用计数;对象被引用或不被引用。如果您需要实际的引用计数,那么我建议在中的RefCountDisposable上构建,这是一个引用计数的IDisposable。

我将以不同的方式处理此问题。我可能会在内部保留对对象的弱引用,但我会返回对它的硬引用。使用者不应该从资源管理器中删除该项,除非他们知道他们只有对该项的引用,并且不需要该项。否则,它们应该只允许系统确定何时删除引用的对象。这样,只要存在对对象的硬引用,它就会保留在内存中。您可以将其从字典中删除,但您只能删除该条目,即,对它的任何新请求都必须创建一个新对象,即使其他使用者有对旧对象的引用。如果弱引用不是活动的,检索过程应该重新创建对象

public ResourceManager<T>
{
     private Dictionary<uint,WeakReference> Cache = new Dictionary<uint,WeakReference>();

     public T this[uint key]
     {
         var obj = (T)this.Cache[key].Target;
         if (obj == null)
         {
             obj = ...recreate resource...
             this.Cache[key] = obj;
         }
         return obj;
     }

     public void Remove( uint key )
     {
         this.Cache.Remove(key);
     }
}

谢谢,那很有用。我不知道有这么好的自清除数据结构:嗯,我刚刚看到,这也只是在.NET4.0中可用。。糟透了。不过还是要谢谢你!据我所知,这些缓存对象只在.NET4.0中可用,但我现在使用的是3.5,我不确定是否会很快迁移到4.0,但谢谢!3.5版的企业库中提供了缓存,3.5版和4.0版都提供了RefCountDisposable。实际上,我得到了强引用,问题是,如果消费者取消了其引用,字典中的条目仍然存在,我必须在某个时候清理它,或者我想这就是你的意思,重复使用条目?但是我想我必须为我的资源对象实现IDisposable接口才能真正释放纹理对象。我的整个想法是能够直接删除资源,但我想我必须重新考虑一下。好的,通过添加IDisposable的使用,您的解决方案可以正常工作。谢谢
public ResourceManager<T>
{
     private Dictionary<uint,WeakReference> Cache = new Dictionary<uint,WeakReference>();

     public T this[uint key]
     {
         var obj = (T)this.Cache[key].Target;
         if (obj == null)
         {
             obj = ...recreate resource...
             this.Cache[key] = obj;
         }
         return obj;
     }

     public void Remove( uint key )
     {
         this.Cache.Remove(key);
     }
}