我有一个多线程应用程序和一个CancellationToken
被用作共享对象。每个线程都可以触发它告诉其他线程工作被取消。然后一个线程进行清理并处理每个对象,如CancellationToken
。然后,如果某个线程尝试使用它,则会引发异常:如何找出一个对象已经处理?
CancellationTokenSource已被丢弃。
如何在使用它之前找出一个对象被丢弃?
我有一个多线程应用程序和一个CancellationToken
被用作共享对象。每个线程都可以触发它告诉其他线程工作被取消。然后一个线程进行清理并处理每个对象,如CancellationToken
。然后,如果某个线程尝试使用它,则会引发异常:如何找出一个对象已经处理?
CancellationTokenSource已被丢弃。
如何在使用它之前找出一个对象被丢弃?
那么,根据反射器,CancellationTokenSource
有一个内部的IsDisposed
方法,可以告诉你,但由于它是内部的,你不应该叫它。在任何情况下,如果一个线程抽出了其他线程依赖的数据结构和对象,则不要这样做。修复你的代码,并让这些对象在需要的时候保持活动状态。
换句话说,等待这些其他线程完成需要CancellationTokenSource
,然后再处理它。
检查对象是否在使用之前进行处理。
仍然不是最好的设计模式。然而,这里是我用来确定一个对象是否被处置。
if (!object.IsDisposed) object.DoSomething();
或
public string DoSomething()
{
if (this.IsDisposed) return null;
}
如果不工作,你可以尝试添加IsDisposed标志并重写Dispose方法。并在您自己的代码中将其设置为true。
适当的行动方案应该是让一些Disposable对象的创建者稍微违反Microsoft的“规则”,即对处置对象执行任何操作时应抛出异常,而应遵循更一般的规则,即异常应该任何时候都会抛出一个方法的后置条件无法满足。如果取消方法的目的是确保没有人会继续将工作视为存活,甚至在取消方法被调用之前,每个人都认为工作已经死亡,那么无论物体是否被丢弃。
通常,设计良好的对象之外的代码不需要查询它是否已被处置,除非可能断言它已被处置。相反,对象本身应该提供方法,其对处置对象的含义将是清晰明确的。这些方法可能在内部使用IsDisposed标志,但必须使用任何锁定来防止竞争条件。通常,图案
if (!myThing.isDisposed) myThing.DoSomething();
是myThing应该真正支持DoSomethingIfNotDisposed方法(可能称为TryDoSomething)的指示。如果你不能这样做,我的倾向可能是编写自己的DoSomethingIfNotDisposed扩展方法,并使用Try/Catch来扼杀ObjectDisposedException(或对象将抛出的任何特定异常)。
继承你的类并添加属性:
class MyCancellationTokenSource: CancellationTokenSource
{
public bool MyIsDisposed { get; private set; }
protected override void Dispose(bool disposing)
{
base.Dispose(disposing);
MyIsDisposed = true;
}
}
为什么一个线程仍在使用的清理资源?这对我来说似乎是一个很大的设计缺陷。 – 2011-04-13 20:41:44
'CancellationToken'用于同步。这发生在两个线程同时尝试取消作业时发生。也许锁定它有助于? – Xaqron 2011-04-13 20:43:40
请解决你的问题btw,你不处理'CancellationToken',这是不能做到的。您正在使用'CancellationTokenSource'。 – 2011-04-13 20:45:17