有没有办法无限期地暂停一个线程? [英] Is there a way to indefinitely pause a thread?

查看:28
本文介绍了有没有办法无限期地暂停一个线程?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在空闲时间一直在开发一个网络爬行 .NET 应用程序,我想要包含的这个应用程序的一个功能是暂停特定线程的暂停按钮.

I've been working on a web crawling .NET app in my free time, and one of the features of this app that I wanted to included was a pause button to pause a specific thread.

我对多线程比较陌生,我无法找到一种方法来无限期地暂停当前支持的线程.我不记得确切的类/方法,但我知道有一种方法可以做到这一点,但它已被 .NET 框架标记为过时.

I'm relatively new to multi-threading and I haven't been able to figure out a way to pause a thread indefinitely that is currently supported. I can't remember the exact class/method, but I know there is a way to do this but it has been flagged as obsolete by the .NET framework.

有没有什么好的通用方法可以在 C# .NET 中无限期地暂停工作线程.

Is there any good general purpose way to indefinitely pause a worker thread in C# .NET.

我最近没有太多时间来开发这个应用程序,我最后一次接触它是在 .NET 2.0 框架中.我对 .NET 3.5 框架中存在的任何新功能(如果有的话)持开放态度,但我想知道也适用于 2.0 框架的解决方案,因为这是我在工作中使用的,并且会很好以防万一.

I haven't had a lot of time lately to work on this app and the last time I touched it was in the .NET 2.0 framework. I'm open to any new features (if any) that exist in the .NET 3.5 framework, but I'd like to know of solution that also works in the 2.0 framework since that's what I use at work and it would be good to know just in case.

推荐答案

永远不要使用 Thread.Suspend.它的主要问题是 99% 的时间您都不知道挂起线程时该线程在做什么.如果该线程持有锁,则更容易陷入死锁等情况.请记住,您正在调用的代码可能会在幕后获取/释放锁.Win32 有一个类似的 API:SuspendThreadResumeThread.SuspendThread 的以下文档很好地总结了 API 的危险:

Never, ever use Thread.Suspend. The major problem with it is that 99% of the time you can't know what that thread is doing when you suspend it. If that thread holds a lock, you make it easier to get into a deadlock situation, etc. Keep in mind that code you are calling may be acquiring/releasing locks behind the scenes. Win32 has a similar API: SuspendThread and ResumeThread. The following docs for SuspendThread give a nice summary of the dangers of the API:

http://msdn.microsoft.com/en-us/library/ms686345(VS.85).aspx

此函数主要供调试器使用.它不打算用于线程同步.如果调用线程尝试获取挂起线程拥有的同步对象,则在拥有同步对象(例如互斥锁或临界区)的线程上调用 SuspendThread 可能会导致死锁.为避免这种情况,应用程序中不是调试器的线程应该通知另一个线程挂起自己.必须将目标线程设计为监视此信号并做出适当响应.

This function is primarily designed for use by debuggers. It is not intended to be used for thread synchronization. Calling SuspendThread on a thread that owns a synchronization object, such as a mutex or critical section, can lead to a deadlock if the calling thread tries to obtain a synchronization object owned by a suspended thread. To avoid this situation, a thread within an application that is not a debugger should signal the other thread to suspend itself. The target thread must be designed to watch for this signal and respond appropriately.

无限期挂起线程的正确方法是使用 ManualResetEvent.该线程很可能正在循环执行一些工作.挂起线程的最简单方法是让线程在每次迭代时检查"事件,如下所示:

The proper way to suspend a thread indefinitely is to use a ManualResetEvent. The thread is most likely looping, performing some work. The easiest way to suspend the thread is to have the thread "check" the event each iteration, like so:

while (true)
{
    _suspendEvent.WaitOne(Timeout.Infinite);

    // Do some work...
}

您指定了一个无限超时,这样当事件没有发出信号时,线程将无限期地阻塞,直到事件发出信号,此时线程将从停止的地方恢复.

You specify an infinite timeout so when the event is not signaled, the thread will block indefinitely, until the event is signaled at which point the thread will resume where it left off.

您可以像这样创建事件:

You would create the event like so:

ManualResetEvent _suspendEvent = new ManualResetEvent(true);

true 参数告诉事件以信号状态开始.

The true parameter tells the event to start out in the signaled state.

当您想暂停线程时,请执行以下操作:

When you want to pause the thread, you do the following:

_suspendEvent.Reset();

并恢复线程:

_suspendEvent.Set();

您可以使用类似的机制来通知线程退出并等待两个事件,检测哪个事件被通知.

You can use a similar mechanism to signal the thread to exit and wait on both events, detecting which event was signaled.

只是为了好玩,我将提供一个完整的示例:

Just for fun I'll provide a complete example:

public class Worker
{
    ManualResetEvent _shutdownEvent = new ManualResetEvent(false);
    ManualResetEvent _pauseEvent = new ManualResetEvent(true);
    Thread _thread;

    public Worker() { }

    public void Start()
    {
        _thread = new Thread(DoWork);
        _thread.Start();
    }

    public void Pause()
    {
        _pauseEvent.Reset();
    }

    public void Resume()
    {
        _pauseEvent.Set();
    }

    public void Stop()
    {
        // Signal the shutdown event
        _shutdownEvent.Set();

        // Make sure to resume any paused threads
        _pauseEvent.Set();

        // Wait for the thread to exit
        _thread.Join();
    }

    public void DoWork()
    {
        while (true)
        {
            _pauseEvent.WaitOne(Timeout.Infinite);

            if (_shutdownEvent.WaitOne(0))
                break;

            // Do the work here..
        }
    }
}

这篇关于有没有办法无限期地暂停一个线程?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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