开发者

How to find out an object has disposed?

开发者 https://www.devze.com 2023-02-24 21:07 出处:网络
I have a multi-threaded application and a CancellationToken is used as a shared object. Every thread can trigger it to tell the other threads the job is cancelled. Then one thread does the clean-up an

I have a multi-threaded application and a CancellationToken is used as a shared object. Every thread can trigger it to tell the other threads the job is cancelled. Then one thread does the clean-up and disposes every object like this CancellationToken. Then if a thread tries to use it, an exception is raised:

The CancellationTokenSource has been disposed.

How can I find out an object is 开发者_运维技巧disposed before using it?


Well, according to Reflector, CancellationTokenSource has an internal IsDisposed method that could've told you, but since it's internal, you're not supposed to call it.

In any case, if one thread yanks out data structures and objects other threads depend on, then don't do that. Fix your code and leave those objects live for the duration of their need.

In other words, wait for those other threads to finish needing the CancellationTokenSource before you dispose of it.


The proper course of action would be for the creators of some Disposable objects to go slightly against Microsoft's "rule" that performing any action on a disposed object should throw an exception, and instead follow the more general rule that an exception should be thrown any time a method's post-conditions can't be met. If the purpose of a Cancel method is to ensure that nobody will continue to regard a job as being live, and even before the Cancel method is called everyone regards the job as being dead, then the post-condition for the method is satisfied regardless of whether the object is disposed.

Generally, code outside a well-designed object shouldn't need to query whether it's been disposed, except possibly to assert that it has been. Instead, the object itself should provide methods whose meaning on a disposed object would be clear and unambiguous. Those methods might internally use an IsDisposed flag, but would have to use whatever locking was necessary to prevent race conditions. In general, the pattern

  if (!myThing.isDisposed) 
    myThing.DoSomething();

is an indication that myThing should really support a DoSomethingIfNotDisposed method (possibly called TryDoSomething). If you can't do that, my inclination might be to write your own DoSomethingIfNotDisposed extension method and use a Try/Catch to stifle an ObjectDisposedException (or whatever particular exception the object would throw).


check if the object is disposed before using it.

Still not the best design pattern. however here is what I use do determine if an object is disposed.

if (!object.IsDisposed) object.DoSomething();

or

public string DoSomething()
{
    if (this.IsDisposed) return null;
}

if that does not work, you may try adding an IsDisposed flag and overriding the dispose method. And setting that to true in your own code.


Inherit your class and add the property:

class MyCancellationTokenSource: CancellationTokenSource
{
    public bool MyIsDisposed { get; private set; }
    protected override void Dispose(bool disposing)
    {
        base.Dispose(disposing);
        MyIsDisposed = true;
     }
}


I agree with Lasse V. Karlsen. However, if you want it:

bool IsDisposed = true;
var privateInt = tokenSource?.GetType().GetProperty("IsDisposed", 
BindingFlags.Instance | BindingFlags.NonPublic);
if (privateInt != null)
{
   IsDisposed = (bool)privateInt.GetValue(tokenSource);
}
0

精彩评论

暂无评论...
验证码 换一张
取 消