如何在线程执行工作时停止服务(不使用Thread.Abort) [英] How to stop a service when a thread is doing work (without using Thread.Abort)

查看:81
本文介绍了如何在线程执行工作时停止服务(不使用Thread.Abort)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个服务循环运行一些不同的任务,直到该服务停止为止. 但是,这些任务之一是我调用Web服务,而此调用可能需要几分钟才能完成.我希望能够立即停止该服务,而无需调用Thread.Abort来取消" Web服务调用,因为即使线程正在做的唯一事情就是调用此Web服务方法,这也会引起一些奇怪的行为.

I have a service running some different tasks in a loop until the service is stopped. However one of these tasks i calling a web service and this call can take several minutes to complete. I want to be able to stop the service instantly, 'cancelling' the web service call without calling Thread.Abort because that causes some strange behavior even if the only thing the thread is doing is calling this web service method.

如何取消或中断同步方法调用(如果可能的话)? 还是应该尝试其他方法?

How can i cancel or break from a synchronous method call (if it's even possible)? Or should I try a different approach?

我尝试使用AutoResetEvent,然后调用Thread.Abort,这在下面的代码示例中运行良好,但是在实际服务中实施此解决方案时,我得到了一些意外的行为,可能是由于我正在使用的外部库.

I have tried to use the AutoResetEvent and then calling Thread.Abort which is working fine in the below code sample, but when implementing this solution in the actual service I get some unexpected behavior probably because of what's going on in the external libraries I'm using.

AutoResetEventThread.Abort:

class Program
{
    static void Main(string[] args)
    {
        MainProgram p = new MainProgram();
        p.Start();
        var key = Console.ReadKey();
        if (key.Key == ConsoleKey.Q)
            p.Stop();
    }
}

class MainProgram
{
    private Thread workerThread;
    private Thread webServiceCallerThread;
    private volatile bool doWork;

    public void Start()
    {
        workerThread = new Thread(() => DoWork());
        doWork = true;
        workerThread.Start();
    }

    public void Stop()
    {
        doWork = false;
        webServiceCallerThread.Abort();
    }

    private void DoWork()
    {
        try
        {
            while (doWork)
            {
                AutoResetEvent are = new AutoResetEvent(false);
                WebServiceCaller caller = new WebServiceCaller(are);
                webServiceCallerThread = new Thread(() => caller.TimeConsumingMethod());
                webServiceCallerThread.Start();

                // Wait for the WebServiceCaller.TimeConsumingMethod to finish
                WaitHandle.WaitAll(new[] { are });

                // If doWork has been signalled to stop
                if (!doWork)
                    break;

                // All good - continue
                Console.WriteLine(caller.Result);
            }
        }
        catch (Exception e)
        {
            Console.Write(e);
        }
    }
}

class WebServiceCaller
{
    private AutoResetEvent ev;
    private int result;

    public int Result
    {
        get { return result; }
    }

    public WebServiceCaller(AutoResetEvent ev)
    {
        this.ev = ev;
    }

    public void TimeConsumingMethod()
    {
        try
        {
            // Simulates a method running for 1 minute
            Thread.Sleep(60000);
            result = 1;
            ev.Set();
        }
        catch (ThreadAbortException e)
        {
            ev.Set();
            result = -1;
            Console.WriteLine(e);
        }
    }
}

有人可以建议解决此问题的方法吗?

Can someone suggest a solution to this issue?

推荐答案

解决方案非常简单:不要阻塞数分钟的呼叫,除非您想阻塞数分钟.如果没有办法不阻塞地做某件事,可能要持续几分钟,所以请大声抱怨谁编写了施加该痛苦要求的代码(或者,如果可能,请自行修复).

The solution is really this simple: Don't make calls that block for several minutes unless you want to block for several minutes. If there is no way to do a particular thing without blocking, potentially for several minutes, complain loudly to whoever wrote the code that imposes that painful requirement (or fix it yourself, if possible).

拨打电话后,为时已晚.你很投入如果您正在调用的函数没有提供安全的方法来中止它,那么就没有安全的方法.

Once you've made the call, it's too late. You're committed. If the function you are calling doesn't provide a safe way to abort it, then there's no safe way.

这篇关于如何在线程执行工作时停止服务(不使用Thread.Abort)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆