我正在做一些TCP编程,我想模拟一些延迟。
每条"消息" (表示序列化对象的byte [])必须延迟一段时间t
。我以为我可以使用一个函数来收集原始消息:
private Queue<byte[]> rawMessages = new Queue<byte[]>();
private void OnDataReceived(object sender, byte[] data)
{
rawMessages.Enqueue(data);
}
另一种方法,使用while循环连续读取rawMessages
然后延迟每一个:
private Queue<byte[]> delayedRawMessages = new Queue<byte[]>();
delayMessagesInTask = Task.Factory.StartNew(() =>
{
while (true) //TODO: Swap a cancellation token
{
if(rawMessages.Count > 0){
var rawMessage = rawMessages.Dequeue();
//???
//Once the message has been delayed, enqueue it into another buffer.
delayedRawMessages.Enqueue(rawMessage);
}
}
});
我认为要延迟每条消息,我可以使用另一种方法来生成一个线程,该线程使用Thread.Sleep(t)
等待时间t
,然后将delayedRawMessages
入队。我确信这会奏效,但我认为必须有更好的方法。 Thread.Sleep
方法的问题是消息2可能在消息1之前完成延迟...我显然需要将消息延迟并以正确的顺序完成,否则我会不使用TCP。
我正在寻找一种方法来尽可能地延迟时间t
,并且不会通过降低速度来影响应用程序的其余部分。
有没有人知道更好的方法吗?
答案 0 :(得分:0)
我决定采用生产者/多种消费者的方法。
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Threading;
using System.Threading.Tasks;
public class LatencySimulator {
public enum SimulatorType { UP, DOWN };
public SimulatorType type;
public int latency = 0;
public int maxConsumers = 50;
public BlockingCollection<byte[]> inputQueue = new BlockingCollection<byte[]>(new ConcurrentQueue<byte[]>());
public Queue<byte[]> delayedMessagesQueue = new Queue<byte[]>();
void CreateConsumers()
{
for (int i = 0; i < maxConsumers; i++)
{
Task.Factory.StartNew(() => Consumer(),TaskCreationOptions.LongRunning);
}
}
private void Consumer()
{
foreach (var item in inputQueue.GetConsumingEnumerable())
{
Thread.Sleep(latency);
delayedMessagesQueue.Enqueue(item);
}
}
}
要使用它,请创建一个新的LatencySimulator
,设置其类型&#39;,最大消费者和模拟延迟。致电CreateConsmers()
,然后填充inputQueue
。邮件延迟后,它们将显示在delayedMessagesQueue
。
我真的不知道这是否是实现我的目标的理想方式,但它现在有效......