如何摆脱您的问题的一个想法可能是双缓冲线程循环。这是实现游戏循环的一个很好的概念,但它也可能满足您的需求。
您将有一个线程在无限循环中执行 PROCESS_DATA,而另一个线程在无限循环中执行 SEND_DATA_TO_CLIENT。你有两个缓冲区。这可以是任何类型的类或保存由 PROCESS_DATA 方法返回的信息的结构。
SEND_DATA_TO_CLIENT 循环首先被锁定,直到 buffer_1 被 PROCESS_DATA 线程填充。然后 PROCESS_DATA 释放 SEND_DATA_TO_CLIENT 上的锁并交换缓冲区。现在 SEND_DATA_TO_CLIENT 拥有已填充的缓冲区并可以随心所欲地处理数据。在此过程中,PROCESS_DATA 同时处理下一个数据并等待 SEND_DATA_TO_CLIENT 完成或解锁 SEND_DATA_TO_CLIENT 以交换缓冲区。
我希望你明白我的意思。如果没有,我可以给你一张图片。
/// <summary>
/// Author: Samuel Egger
/// </summary>
class Program
{
private static EventWaitHandle swappedWh = new EventWaitHandle(false, EventResetMode.AutoReset);
private static object lockerA = new object();
private static object lockerB = new object();
private static int counter = 0;
// The queues can be of any type which holds your data e.g. a struct or a class
private static Queue<string> dataQueueA = new Queue<string>();
private static Queue<string> dataQueueB = new Queue<string>();
static void Main(string[] args)
{
Thread sendDataToClientThread = new Thread(SendDataToClient);
Thread processDataThread = new Thread(ProcessData);
sendDataToClientThread.IsBackground = false;
processDataThread.Start();
sendDataToClientThread.Start();
}
private static void ProcessData()
{
while (true)
{
lock (lockerA)
{
// Your time consuming process goes here. The result then must
// must be saved (e.g. state) and then enqueued
dataQueueA.Enqueue(state);
}
// If the operations result is equal to 2, then the render thread is done
// and is waitung for getting unblocked
if (Interlocked.Increment(ref counter) == 2)
{
counter = 0;
SwapQueues();
swappedWh.Set();
}
else
{
swappedWh.WaitOne();
}
}
}
private static void SendDataToClient()
{
while (true)
{
lock (lockerB)
{
// Send the data generated by the process data thread
while (dataQueueB.Count > 0)
{
string data = dataQueueB.Dequeue();
// Your process of sending the data goes here
}
}
if (Interlocked.Increment(ref counter) == 2)
{
counter = 0;
SwapQueues();
swappedWh.Set();
}
else
{
swappedWh.WaitOne();
}
}
}
static void SwapQueues()
{
// Wait until both threads are "done" before swapping
lock (lockerA)
{
lock (lockerB)
{
Queue<string> tmpQueue = dataQueueA;
dataQueueA = dataQueueB;
dataQueueB = tmpQueue;
}
}
}
}
我希望这个小技巧的例子会对你有所帮助。