English 中文(简体)
在一个复杂的物体图表中可支配的、无法管理的资源的终身问题?
原标题:Lifetime issue of IDisposable unmanaged resources in a complex object graph?

问题在于处理未经管理的资源(COM interop),并确保任何资源泄漏。 我很赞赏对我是否以正确方式行事的反馈意见。

Background:


请允许我说,我有两个班子:

  • a 类别<代码>LimitedComResource,该类别围绕一个COM标(通过一些APIC获得)。 只有为数有限的这些COM物体,因此,我的班子实施<代码>。 IDisposable cross which will be responsible for releaseing a COM Object when it s no term need.

  • 另一种类型的物体:ManagedObject 暂时创建,以便在上做一些工作。 LimitedComResource。 页: 1 IDisposable。

为了用图表总结上述内容,我的班子可能这样做:

            +---------------+           +--------------------+
            | ManagedObject | <>------> | LimitedComResource |
            +---------------+           +--------------------+
                                                  |
                                                  o IDisposable

(我仅举一个例子,说明这两个班的代码。)

Question:


自我的临时<代码>以来 目标物体不可弃置,我显然无法控制其残ll多久。 然而,与此同时,我可能还有<代码>Disposed>,LimitedComObject: a ManagedObject。 www.un.org/Depts/DGACM/index_french.htm ......

            +---------------+           +--------------------+
            | managedObject | <>------> |   (dead object)    |
            +---------------+           +--------------------+

我目前正在实施这一规定时,在<条码>中,有各种参考文献软弱和旗帜,表明某一物体是否已经处置。Is there any better way?

Example code (what I ve currently got):


LimitedComResource:

class LimitedComResource : IDisposable
{
    private readonly IUnknown comObject;  // <-- set in constructor

    ...

    void Dispose(bool notFromFinalizer)
    {
        if (!this.isDisposed)
        {
            Marshal.FinalReleaseComObject(comObject);
        }
        this.isDisposed = true;
    }

    internal bool isDisposed = false;
}

ManagedObject:

class ManagedObject
{
    private readonly WeakReference limitedComResource;  // <-- set in constructor

    ...

    public void DoSomeWork()
    {
        if (!limitedComResource.IsAlive())
        {
            throw new ObjectDisposedException();
            //        ^^^^^^^^^^^^^^^^^^^^^^^
            //  is there a more suitable exception class?
        }

        var ur = (LimitedComResource)limitedComResource.Target;
        if (ur.isDisposed)
        {
            throw new ObjectDisposedException();
        }

        ...  // <-- do something sensible here!
    }
}
最佳回答

Nope, this is not okay. 缩略语只有告诉你,所收集的有管理的物体是垃圾。 这与国际发展法无关。 处置点是释放未管理的资源, 直至 为止,垃圾收集者这样做。

事实上,如果所管理物体是第1号基因,则你会遇到一个严重问题,而孔普则是第0号基因。 WeakReference可能不会活下来,而是会收集,在你有机会叫迪斯())之前处置COM物体。

只是简单地提及贵方管理的物体。 在你要求处置之后,你可以将其搁置起来,以便收集包装材料。 如果客户守则试图加以使用,而提及无效,就会放弃反对。 或者,如果是这样的话,则重新计算。

问题回答

当你投下物体类型提及不力的目标时,如果该物体被处置,则该物体将失效。 简单检查一下,看看你回来的价值在开展行动之前是否无效。 见文件。 也可在Using Weak reference上找到这一条。 本条的相关引文如下:

To establish a strong reference and use the object again, cast the Target property of a WeakReference to the type of the object. If the Target property returns null, the object was collected; otherwise, you can continue to use the object because the application has regained a strong reference to it.

例:

class ManagedObject 
{ 
    private readonly WeakReference limitedComResource;  // <-- set in constructor 

    ... 

    public void DoSomeWork() 
    { 
        var ur = (LimitedComResource)limitedComResource.Target; 
        if (ur == null) 
        { 
            throw new ObjectDisposedException(); 
        } 

        ...  // <-- do something sensible here! 
    } 
}




相关问题
Manually implementing high performance algorithms in .NET

As a learning experience I recently tried implementing Quicksort with 3 way partitioning in C#. Apart from needing to add an extra range check on the left/right variables before the recursive call, ...

Anyone feel like passing it forward?

I m the only developer in my company, and am getting along well as an autodidact, but I know I m missing out on the education one gets from working with and having code reviewed by more senior devs. ...

How do I compare two decimals to 10 decimal places?

I m using decimal type (.net), and I want to see if two numbers are equal. But I only want to be accurate to 10 decimal places. For example take these three numbers. I want them all to be equal. 0....

Exception practices when creating a SynchronizationContext?

I m creating an STA version of the SynchronizationContext for use in Windows Workflow 4.0. I m wondering what to do about exceptions when Post-ing callbacks. The SynchronizationContext can be used ...

Show running instance in single instance application

I am building an application with C#. I managed to turn this into a single instance application by checking if the same process is already running. Process[] pname = Process.GetProcessesByName("...

How to combine DataTrigger and EventTrigger?

NOTE I have asked the related question (with an accepted answer): How to combine DataTrigger and Trigger? I think I need to combine an EventTrigger and a DataTrigger to achieve what I m after: when ...