【发布时间】:2018-04-06 19:06:55
【问题描述】:
在这个实现中,Task.Factory.StartNew 永远不会将线程返回到线程池,因为它包含带有 Thread.Sleep 的 while(true)。这样对吗?如何查看queue是否有任务需要完成?
namespace ConsoleApplication1
{
class Program
{
static void Main(string[] args)
{
Helper h = new Helper();
PlayWithQueue s = new PlayWithQueue();
s.AddToQueueForExecution(() => { h.Indicate(1); });
s.AddToQueueForExecution(() => { h.Indicate(2); });
s.AddToQueueForExecution(() => { h.Indicate(3); });
s.AddToQueueForExecution(() => { h.Indicate(4); });
s.AddToQueueForExecution(() => { h.Indicate(5); });
s.AddToQueueForExecution(() => { h.Indicate(6); });
Console.ReadKey();
}
}
public class PlayWithQueue
{
private readonly ConcurrentQueue<Action> queue = new ConcurrentQueue<Action>();
public PlayWithQueue()
{
var task = Task.Factory.StartNew(ThreadProc);
}
public void AddToQueueForExecution(Action action)
{
queue.Enqueue(action);
}
private void ThreadProc()
{
while (true)
{
Action item;
bool isSuccessfull = false;
isSuccessfull = queue.TryDequeue(out item);
if (isSuccessfull)
{
item();
}
System.Threading.Thread.Sleep(100);
}
}
}
public class Helper
{
public void Indicate(int number)
{
Random rnd = new Random();
int timeDelay = rnd.Next(1000, 5000);
Console.WriteLine("Start" + number.ToString());
System.Threading.Thread.Sleep(timeDelay);
Console.WriteLine("End" + number.ToString() + " " + timeDelay.ToString());
}
}
}
【问题讨论】:
-
是的,你永远窃取了一个 ThreadPool 线程。
How to check queue that it has task that need to be done?是什么意思? -
@FCin,没有 while(true) 有什么更好的解决方案?
-
如果你打算有一个像这样运行很长时间的线程,不要使用线程池,只需创建一个真正的
Thread。将线程池用于这样的事情最终会引入额外的复杂性。 -
如果你真的想正确地做到这一点,请查看“生产者/消费者模式”。
-
您可以通过 await Task.Delay 避免保持线程,但仍有更好的方法可以做到这一点。
标签: c# multithreading task-parallel-library