停止执行动作

时间:2013-11-07 12:18:20

标签: c# delegates extension-methods

我有以下扩展方法:

public static void With<T>(this T value, Action<T> action);

我使用如下:

someT.With(x => { /* Do something with x */ })

如何将条件应用于行动执行?类似的东西:

someT.With(x => { /* if (condiction) stopAction */ })

这可能吗?

2 个答案:

答案 0 :(得分:2)

想一想 - 你的行动会从哪里获得condition?您必须将其作为附加参数提供,或者在操作的闭包中捕获它(如果有的话)。或者,如果操作是指向某个Object.Method的普通委托,那么您可以使用任何字段/属性作为条件,但这只是典型的方法实现..

(A)
someT.With( (x,stopConditionHolder) => { while(!stopConditionHolder.StopNow) dosomething; });
// of course, now With() has to get the holder object from somewhere..

(B)
var stopConditionHolder = new ... ();
stopConditionHolder.StopNow = false;
someT.With( (x,stopNow) => { while(!stopConditionHolder.StopNow) dosomething; });

// now you can use the holder object to 'abort' at any time
stopConditionHolder.StopNow = true; // puff!

(C)
class MyAction
{
    public bool stopNow = false;

    public void PerformSomething()
    {
        while(!stopNow)
           dosomething;
    }
}

var actionObj = new MyAction();
someT.With( actionObj.PerformSomething  );
// note the syntax: the PerformSomething is PASSED, not called with ().

// now you can use the holder object to 'abort' at any time
actionObj.stopNow = true; // puff!

此外,您可能希望查看框架的CancellationToken类,该类是为这种“中断”而创建的。 CancellationToken是“标准StopNow持有者”,您可以将其传递到opeartions,然后异步命令它们中止。当然,“操作”必须不时检查该令牌,就像我在while(!stop)中所做的那样。

此外,如果你想“严厉地”中止某些事情,特别是当那件事不是“准备取消”时,你可能想要检查:

  • 在目标线程中引发InterrupedException的Thread.Interrupt,它将从任何Sleep / Wait中“唤醒”它,但是......通过从该方法引发异常
  • 引发ThreadAbortException的Thread.Abort - 同样地,但更苛刻的方式..

但是,这两个都需要您具有对“挂起”的工作线程的精确访问权限。这通常是不可能的。

答案 1 :(得分:0)

我在这里假设你要求过早地中断你之前开始的动作,因为你的问题并不完全清楚。

我认为没有任何内置方法可以做到这一点。如果你在一个单独的线程上执行你的操作,你可以中止该线程,但你应该避免这种情况。

或者,您必须创建一个在循环中执行离散步骤的自定义操作,并在每个步骤之后检查它是否已中止。