简体   繁体   English

从子方法中终止父方法

[英]Terminate parent method from child method

I create a plugin for an application.我为应用程序创建了一个插件。 When a user presses a stop command in the parent application, a global variable to which my plugin has access to is set to true.当用户在父应用程序中按下停止命令时,我的插件有权访问的全局变量将设置为 true。 For a simple method I create, I test this variable and exit:对于我创建的一个简单方法,我测试了这个变量并退出:

public class Status
{
    public static bool CheckTermFlag()
    {
        if (VoiceAttackPlugin._stopVariableToMonitor)
        {
            VoiceAttackPlugin._stopVariableToMonitor = false;
            return true;
        }
        return false;
    }
}

And I place this 'CheckTermFlag' in my code:我将这个“CheckTermFlag”放在我的代码中:

class ForTesting
{
    public static void SendStopAllTest()
    {
        for (int i = 0; i <= 20; i++)
        {
            if (Status.CheckTermFlag())
            {
                return;
            }
            Thread.Sleep(500);
            vaProxy.WriteToLog(i.ToString(), "Green");
        }
    }

The problem is that I may have several methods and each calling another one.问题是我可能有几种方法,每种方法都调用另一种方法。 I can't place a question for "Status.CheckTermFlag()" in every step of my program and propagate it upwards.我无法在我的程序的每一步中都对“Status.CheckTermFlag()”提出问题并将其向上传播。

So how can i 'listen' for this variable from anywhere in my program and terminate/return if required?那么我如何从程序中的任何地方“监听”这个变量并在需要时终止/返回呢?

Why not use a CancellationToken for this?为什么不为此使用CancellationToken You can stop any method by any method that way.您可以通过任何方法停止任何方法。 If a method have access to CTS it can just call Cancel and all methods that have CancellationToken s can then finish whatever they are doing and exit.如果一个方法可以访问CTS ,它可以只调用Cancel ,然后所有具有CancellationToken的方法都可以完成它们正在做的任何事情并退出。

In multithreading environment a SemaphoreSlim can be used as an awaitable reset event as a mean of synchronizing threads.在多线程环境中, SemaphoreSlim可以用作可等待的重置事件,作为同步线程的一种方式。

I wouldn't use Thread.Abort() , it's good for the threads you have no control over.我不会使用Thread.Abort() ,这对您无法控制的线程很有用。 But if it's all your code and you control it - it's always better just to signal between threads and ask them nicely to terminate, that leads to less undefined states and behaviors later.但是,如果它是您的所有代码并且您可以控制它 - 最好只是在线程之间发出信号并要求它们很好地终止,这会导致以后更少的未定义状态和行为。

BTW, just make either the CancellationTokenSource accessible to methods that should stop the calling method, or made an accessible method that calls Cancel() on CTS .顺便说一句,只需让应该停止调用方法的方法可以访问CancellationTokenSource ,或者创建一个在CTS上调用Cancel()的可访问方法。 I used that approach a lot in a high-load.network gateway and a desktop application that downloaded a large number of files parallelly.我在高负载网络网关和并行下载大量文件的桌面应用程序中使用了很多这种方法。 The cost of it is negligible.它的成本可以忽略不计。 Don't be afraid of disposables, used correctly they save more time than it takes to handle them.不要害怕一次性用品,正确使用它们可以节省比处理它们更多的时间。

In a multi-threaded scenario the way to go is the Thread.Abort() method.在多线程场景中,通往 go 的方法是Thread.Abort()方法。 It throws the ThreadAbortException in the target thread, causing it to terminate.它在目标线程中抛出ThreadAbortException ,导致它终止。

If you, for whatever reason, need a custom solution, do it likewise.如果您出于某种原因需要自定义解决方案,请照此操作。 Throw an exception, and handle it at the top-most method where it makes sense.抛出异常,并在有意义的最顶层方法中处理它。 Like this:像这样:

public class TerminateProcessingExeption : Exception { … }

…

public static bool CheckTermFlag()
{
    if (VoiceAttackPlugin._stopVariableToMonitor)
    {
        VoiceAttackPlugin._stopVariableToMonitor = false;
        throw new TerminateProcessingExeption();
    }
}

In addition, instead of a bool flag, consider using an AutoResetEvent .此外,考虑使用AutoResetEvent而不是bool标志。 Look into the example in the documentation for more information.查看文档中的示例以获取更多信息。 A simple variable won't shield you from the adverse effects of concurrent memory access in multi-processor setups.一个简单的变量不会使您免受多处理器设置中并发 memory 访问的不利影响。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM