none
如何控制 ThreadPool 的执行和停止? RRS feed

  • 问题

  •         private System.Threading.Timer ThreadTimer;

            private Semaphore m_Semaphore;

            private void Init()
            {
                m_Semaphore = new Semaphore(1, 1);
            }

            private void TimeCallBack(object obj)
            {
                ThreadTimer.Dispose();
                if (条件符合)
                {
                    执行其它处理
                }
                else
                {
                    m_Semaphore.Release();
                    this.Invoke(new dg_PrintInfo(PrintContent), new object[] { "超时." });
                }
            }

            private void PushTask_Click()  //有一个按钮执行添加任务
            {
                ThreadPool.QueueUserWorkItem(new WaitCallback(TaskExec));

                return true;
            }

            private void TaskExec(object state)
            {
                m_Semaphore.WaitOne();

                ThreadTimer = new System.Threading.Timer(new System.Threading.TimerCallback(TimeCallBack));

                ThreadTimer.Change(1000, 50);           

                return;
            }

     

    求鉴定这种模型是否可行?

    合理吗?

    ThreadPool.QueueUserWorkItem执行后,线程立即执行了,能否控制ThreadPool何时执行何时停止?因为我希望能先把所有任务线程压入池内,才开始执行。


    2013年1月10日 2:29

答案

全部回复

  • dear

    1.基本上不建议使用Timer来处理,万一 interval 的时间无法满足真正处理时间,就会有问题,也就是说世情还没处理完,timer又把工作派进来。建議使用以下方式处理,利用 IsStart 旗标停止thread

    ThreadPool.QueueUserWorkItem(o =>
    {
        while (true)
        {
            if (!this.IsStart)
            {
                break;
            }
    
            //TODO:处理要做的事
        }
    });

    2.threadpool 没法子立即停止thread,还是需要等到功能完成,thread 才会真正停止

    3.你可以控制thread启动顺序

    http://www.dotblogs.com.tw/yc421206/archive/2011/08/14/33104.aspx

    4.若你需要stop、suspend、resume功能,你可能需要考虑使用 Task class,或是自己控制 thread class


    秘訣無它,唯勤而已 http://www.dotblogs.com.tw/yc421206/

    • 已标记为答案 KingSoft.H 2013年1月12日 1:24
    2013年1月10日 3:54
  • 非常感谢你的帮助,还有一些问题,在线程内加入循环检测状态标记(IsStart),万一 isStart 在外部没有被改变状态,线程就回陷入无限期等待了。对此,是否有办法在线程内加入一个最大允许延时,超出这个延时后,线程强制释放信号量,无条件终止执行?  谢谢。
    • 已标记为答案 KingSoft.H 2013年1月12日 1:24
    2013年1月10日 6:59
  • dear

    我不是很了解你要做啥,或许你可以在描述清楚一点。

    并不会进入 thread 等待,他仍在背景工作,不会影响主线程,所谓 thread 等待会造成软件瘫痪,比如死锁

    http://www.dotblogs.com.tw/yc421206/archive/2011/01/18/20878.aspx

    你可利用按钮事件来改变IsStart的状态,

    或是利用 Stopwatch

    Stopwatch sw = new Stopwatch();
    sw.Start();
    //TODO:功能处理
    sw.Stop();
    if (sw.ElapsedMilliseconds>1000)
    {
        //TODO:离开循环
    }

    或是使用 WaitHandle.WaitOne 方法

    http://www.dotblogs.com.tw/yc421206/archive/2011/01/06/20609.aspx

    http://www.dotblogs.com.tw/yc421206/archive/2011/08/14/33105.aspx

    http://www.dotblogs.com.tw/yc421206/archive/2011/08/14/33104.aspx


    若你的工作需要等待 thread 回传结果那就可以选择 WaitOne(int)


    秘訣無它,唯勤而已 http://www.dotblogs.com.tw/yc421206/

    • 已标记为答案 KingSoft.H 2013年1月12日 1:24
    2013年1月10日 8:25
  • 非常感谢你的帮助,研究了你给出的多个方案,学习了不少。小弟还有一个疑问,如何让池内线程的WaitCallback()中使用一种只阻塞当前线程而非进程范围的主线程的延时,并且拥有一个超时机制。超时后,不管状态如何,此线程必须返回或执行其它操作。

    在线程内使用await是不是阻塞的?

    WaitCallback 是线程执行体还是线程完成的回调?看这个参数名,后面是Callback,但前面又有一个Wait,搞模糊了。。。

    谢谢。




    2013年1月12日 1:24