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

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

问题描述

我一直工作在一个网络爬虫在我的空闲时间.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%的时间你可以不知道,当你将其挂起什么线程正在做的事情。如果线程持有的锁,你更容易进入一个死锁情况等请记住,code您呼叫可获取/释放幕后锁。 Win32的也有类似的API: SuspendThread ResumeThread 。为 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:

<一个href="http://msdn.microsoft.com/en-us/library/ms686345(VS.85).aspx">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.

您将创建活动像这样:

ManualResetEvent _suspendEvent = new ManualResetEvent(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..
        }
    }
}

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

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