Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/299.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 临时挂起工作线程的正确方法_C#_.net_Multithreading_Sleep_Worker - Fatal编程技术网

C# 临时挂起工作线程的正确方法

C# 临时挂起工作线程的正确方法,c#,.net,multithreading,sleep,worker,C#,.net,Multithreading,Sleep,Worker,我有一个工作线程,它可能在短时间内处于活动状态,而在其余时间处于空闲状态。我在考虑让线睡觉,然后在需要的时候把它唤醒 我还应该知道关于这方面的其他建议吗 谢谢 这是用C#/.NET4编写的 您可能不应该使用持久工作线程-使用线程池。这正是它的目的 ThreadPool.QueueUserWorkItem(() => { // My temporary work here }); 如果坚持使用持久工作线程,请使其运行以下操作: // This is our latch- we c

我有一个工作线程,它可能在短时间内处于活动状态,而在其余时间处于空闲状态。我在考虑让线睡觉,然后在需要的时候把它唤醒

我还应该知道关于这方面的其他建议吗

谢谢

  • 这是用C#/.NET4编写的

    • 您可能不应该使用持久工作线程-使用线程池。这正是它的目的

      ThreadPool.QueueUserWorkItem(() => {
          // My temporary work here
      });
      
      如果坚持使用持久工作线程,请使其运行以下操作:

      // This is our latch- we can use this to "let the thread out of the gate"
      AutoResetEvent threadLatch = new AutoResetEvent(false);
      
      // The thread runs this
      public void DoBackgroundWork() {
          // Making sure that the thread is a background thread
          // ensures that the endless loop below doesn't prevent
          // the program from exiting
          Thread.IsBackground = true;
          while (true) {
      
              // The worker thread will get here and then block 
              // until someone Set()s the latch:
              threadLatch.WaitOne();
      
              // Do your work here
          }
      }
      
      //  To signal the thread to start:
      threadLatch.Set();
      

      还要注意,如果这个后台线程要与用户界面进行交互,那么您需要相应地调用或开始调用。请参见

      您可能不应该使用持久工作线程-使用线程池。这正是它的目的

      ThreadPool.QueueUserWorkItem(() => {
          // My temporary work here
      });
      
      如果坚持使用持久工作线程,请使其运行以下操作:

      // This is our latch- we can use this to "let the thread out of the gate"
      AutoResetEvent threadLatch = new AutoResetEvent(false);
      
      // The thread runs this
      public void DoBackgroundWork() {
          // Making sure that the thread is a background thread
          // ensures that the endless loop below doesn't prevent
          // the program from exiting
          Thread.IsBackground = true;
          while (true) {
      
              // The worker thread will get here and then block 
              // until someone Set()s the latch:
              threadLatch.WaitOne();
      
              // Do your work here
          }
      }
      
      //  To signal the thread to start:
      threadLatch.Set();
      

      还要注意,如果这个后台线程要与用户界面进行交互,那么您需要相应地调用或开始调用。请参见仅使用事件暂停工作线程:重置-暂停,设置-未暂停(工作)状态

      下面是演示该方法的代码的草稿

      class Worker
      {
          private Thread _thread;
      
          // Un-paused by default.
          private ManualResetEvent _notToBePaused = new ManualResetEvent(true);
      
          public Worker()
          {
              _thread = new Thread(Run)
                  {
                      IsBackground = true
                  };
          }
      
          /// <summary>
          /// Thread function.
          /// </summary>
          private void Run()
          {
              while (true)
              {
                  // Would block if paused!
                  _notToBePaused.WaitOne();
      
                  // Process some stuff here.
              }
          }
      
          public void Start()
          {
              _thread.Start();
          }
      
          public void Pause()
          {
              _notToBePaused.Reset();
          }
      
          public void UnPause()
          {
              _notToBePaused.Set();
          }
      }
      
      类工作者
      {
      私有线程(u线程),;
      //默认情况下取消暂停。
      private ManualResetEvent _nottobepause=新的ManualResetEvent(真);
      公职人员()
      {
      _线程=新线程(运行)
      {
      IsBackground=true
      };
      }
      /// 
      ///线程函数。
      /// 
      私家车
      {
      while(true)
      {
      //如果暂停,将被阻止!
      _nottobepause.WaitOne();
      //在这里处理一些东西。
      }
      }
      公开作废开始()
      {
      _thread.Start();
      }
      公共空间暂停()
      {
      _nottobepause.Reset();
      }
      公共无效取消暂停()
      {
      _nottobepause.Set();
      }
      }
      
      只需使用事件暂停工作线程:重置-暂停,设置-未暂停(工作)状态

      下面是演示该方法的代码的草稿

      class Worker
      {
          private Thread _thread;
      
          // Un-paused by default.
          private ManualResetEvent _notToBePaused = new ManualResetEvent(true);
      
          public Worker()
          {
              _thread = new Thread(Run)
                  {
                      IsBackground = true
                  };
          }
      
          /// <summary>
          /// Thread function.
          /// </summary>
          private void Run()
          {
              while (true)
              {
                  // Would block if paused!
                  _notToBePaused.WaitOne();
      
                  // Process some stuff here.
              }
          }
      
          public void Start()
          {
              _thread.Start();
          }
      
          public void Pause()
          {
              _notToBePaused.Reset();
          }
      
          public void UnPause()
          {
              _notToBePaused.Set();
          }
      }
      
      类工作者
      {
      私有线程(u线程),;
      //默认情况下取消暂停。
      private ManualResetEvent _nottobepause=新的ManualResetEvent(真);
      公职人员()
      {
      _线程=新线程(运行)
      {
      IsBackground=true
      };
      }
      /// 
      ///线程函数。
      /// 
      私家车
      {
      while(true)
      {
      //如果暂停,将被阻止!
      _nottobepause.WaitOne();
      //在这里处理一些东西。
      }
      }
      公开作废开始()
      {
      _thread.Start();
      }
      公共空间暂停()
      {
      _nottobepause.Reset();
      }
      公共无效取消暂停()
      {
      _nottobepause.Set();
      }
      }
      
      用WaitHandle发送信号是正确的方法,但这只是为了补充其他人已经说过的话

      我通常会使用两个信号一起工作,否则在需要的时候你不知道是“继续”还是“退出”——或者不得不采用一种不太优雅的方式(停止线程——当然还有其他类似的方式,只有一种“模式”)。因此,它通常与“退出”信号和“新工作可用”信号协同工作。e、 g

      WaitHandle[] eventArray = new WaitHandle[2] { _exitEvent, _newWorkEvent };
      while ((waitid = WaitHandle.WaitAny(eventArray, timeout, false)) > 1)
      {
          // do your work, and optionally handle timeout etc.
      }
      
      注:
      退出是
      ManualResetEvent
      ,初始状态为“false”-“Set”事件退出。
      \u newWork
      要么是
      手册
      ,在这种情况下,您需要从外部暂停/继续,这正是您想要的-
      …或者也可以是
      new AutoResetEvent(false)
      ,您通过“信号”执行一个循环的工作,信号立即返回到“false”-您需要为每个“新批”工作重复该操作-这有点简化。 (这通常伴随着一些“消息”的传递,当然是以某种方式同步的)


      希望这能增加更多信息,

      用WaitHandle发送信号是正确的方法,但只是补充其他人已经说过的内容

      我通常会使用两个信号一起工作,否则在需要的时候你不知道是“继续”还是“退出”——或者不得不采用一种不太优雅的方式(停止线程——当然还有其他类似的方式,只有一种“模式”)。因此,它通常与“退出”信号和“新工作可用”信号协同工作。e、 g

      WaitHandle[] eventArray = new WaitHandle[2] { _exitEvent, _newWorkEvent };
      while ((waitid = WaitHandle.WaitAny(eventArray, timeout, false)) > 1)
      {
          // do your work, and optionally handle timeout etc.
      }
      
      注:
      退出是
      ManualResetEvent
      ,初始状态为“false”-“Set”事件退出。
      \u newWork
      要么是
      手册
      ,在这种情况下,您需要从外部暂停/继续,这正是您想要的-
      …或者也可以是
      new AutoResetEvent(false)
      ,您通过“信号”执行一个循环的工作,信号立即返回到“false”-您需要为每个“新批”工作重复该操作-这有点简化。 (这通常伴随着一些“消息”的传递,当然是以某种方式同步的)


      希望这能增加更多信息,

      感谢您的关注!我更新了帖子。是什么决定了该线程何时激活?用户输入,如点击按钮或鼠标点击感谢您的关注!我更新了帖子。是什么决定了线程何时应该激活?用户输入,如点击按钮或鼠标单击,您知道QueueUserWorkItem是在一个新线程上执行还是在多个新线程上执行?也就是说,如果您两次调用添加两个独立的工作项,是否可以保证这两个工作项都将按顺序运行,或者通过调用我们完全放弃控制,可以生成多个新线程?后者。除非手动同步它们的工作,否则您将有多个线程。您是否知道QueueUserWorkItem将在一个新线程或多个新线程上执行?也就是说,如果你打两次电话,添加两个独立的工作项,是不是