栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 面试经验 > 面试问答

有没有一种方法可以无限期地暂停线程?

面试问答 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

有没有一种方法可以无限期地暂停线程?

永远不要使用

Thread.Suspend
。它的主要问题是,在挂起线程时,有99%的时间您不知道该线程在做什么。如果该线程持有锁,则可以更容易陷入死锁等情况。请记住,您正在调用的代码可能正在幕后获取/释放锁。Win32具有类似的API:
SuspendThread
ResumeThread
。以下文档为
SuspendThread
API的危害提供了很好的摘要:

http://msdn.microsoft.com/zh-
cn/library/ms686345(VS.85).aspx

此功能主要是供调试器使用的。它不打算用于线程同步。在拥有同步对象(例如互斥锁或关键节)的线程上调用SuspendThread会导致死锁,前提是该调用线程试图获取挂起线程拥有的同步对象。为了避免这种情况,应用程序中的一个不是调试器的线程应该向另一个线程发出信号以挂起自身。目标线程必须设计为监视此信号并适当响应。

无限期挂起线程的正确方法是使用

ManualResetEvent
。线程很可能正在循环执行某些工作。挂起线程的最简单方法是让线程在每次迭代中“检查”事件,如下所示:

while (true){    _suspendEvent.WaitOne(Timeout.Infinite);    // Do some work...}

您可以指定一个无限超时,这样当不通知事件时,线程将无限期阻塞,直到通知事件为止,线程将在该点从中断处继续恢复。

您可以这样创建事件:

ManualResetEvent _suspendEvent = new ManualResetEvent(true);

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

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

_suspendEvent.Reset();

并恢复线程:

_suspendEvent.Set();

您可以使用类似的机制向线程发出信号以退出并等待两个事件,以检测到哪个事件已被发出信号。

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

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..        }    }}


转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/568494.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号