首先,这里有一些我想改进的伪代码。
public List<ProcessData> Processes; System.Threading.Thread ProcessThread; void ProcessLoop() { while (true) { for (int i = 0; i < Processes.Count; i++) { if (HasPriority(Processes[i])) { Process(Processes[i]); } } System.Threading.Thread.Sleep(1000); } } void AddProcessData(ProcessData pd) { Processes.Add(pd); if (Suspended(ProcessThread)) Resume(ProcessThread); } void Startup() { ProcessThread = new System.Threading.Thread(ProcessLoop); ProcessThread.Start(); }
所以我想要做的是将'Sleep'替换为将挂起线程的代码,或让它等待直到某些内容添加到列表然后恢复它。我当然也需要它是线程安全的。
答案 0 :(得分:1)
你想要的是一个事件。
编辑:使其成为线程安全的。
public List<ProcessData> Processes;
System.Threading.Thread ProcessThread;
System.Threading.AutoResetEvent ProcessesChangedEvent = new System.Threading.AutoResetEvent(false);
void ProcessLoop()
{
while (true)
{
// You might want to copy out the entire list as an array instead
// if HasPriority or Process take a long time.
lock (Processes)
{
for (int i = 0; i < Processes.Count; i++)
{
if (HasPriority(Processes[i]))
{
Process(Processes[i]);
}
}
}
ProcessesChangedEvent.WaitOne(...); // timeout?
}
}
void AddProcessData(ProcessData pd)
{
lock (Processes)
Processes.Add(pd);
ProcessesChangedEvent.Set(); // you can also use Monitor.PulseAll/Wait
}
void Startup()
{
ProcessThread = new System.Threading.Thread(ProcessLoop);
ProcessThread.Start();
}
答案 1 :(得分:1)
在您的情况下,最好的决定是使用下一个课程之一:ManualResetEvent或AutoResetEvent
答案 2 :(得分:1)
你真正需要的是BlockingQueue。您可以找到高质量的实施here。或者,如果您使用的是.NET Framework的v4,则可以使用内置的BlockingCollection类。请注意使用此类数据结构时代码的容易程度。
public class YourClass
{
private BlockingQueue<ProcessData> m_Queue = new BlockingQueue<ProcessData();
private void ProcessLoop()
{
while (true)
{
ProcessData item = m_Queue.Dequeue();
if (HasPriority(item))
{
Process(item);
}
}
}
public void AddProcessData(ProcessData item)
{
m_Queue.Enqueue(item);
}
public void Startup()
{
var thread = new Thread(() => { ProcessLoop(); });
thread.Start();
}
}
答案 3 :(得分:0)
了解Microsoft的RX框架。 http://rxwiki.wikidot.com/start 在那里你可以每x秒获得一个事件然后做一些事情。 根本不需要启动线程。
或使用计时器,并检查已用完的事件。
答案 4 :(得分:0)
万一你确实只需要处理一次数据,这里有一些代码
public Queue<ProcessData> Processes;
System.Threading.Thread[] ProcessThreads = new System.Threading.Thread[5];
System.Threading.Semaphore semToDo = new System.Threading.Semaphore(0,int.MaxValue);
void ProcessLoop()
{
ProcessData pd;
while (true)
{
semToDo.WaitOne();
lock (Processes)
{
pd = Processes.Dequeue();
}
Process(pd);
}
}
private void Process(ProcessData processData)
{
throw new NotImplementedException();
}
void AddProcessData(ProcessData pd)
{
lock (Processes)
{
Processes.Enqueue(pd);
}
semToDo.Release();
}
void Startup()
{
//you can even have multiple worker threads now!
for(int i = 0; i < 5; i++)
ProcessThreads[i] = new System.Threading.Thread(ProcessLoop);
foreach (System.Threading.Thread t in ProcessThreads)
{
t.Start();
}
}