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将在一个新线程或多个新线程上执行?也就是说,如果你打两次电话,添加两个独立的工作项,是不是