我有一个长时间运行的进程,它将数据发送到另一台机器。但这些数据是分块接收的(比如一组100个数据包,然后延迟至少10秒(。
我在一个单独的线程上使用Task.Run(() => { SendPackets(); });
要发送的数据包通过一些其他功能在Queue<Packet>
对象中排队。
在SendPackets()
中,我使用while循环来检索和发送(异步(队列中所有可用的项。
void SendPackets()
{
while(isRunning)
{
while(thePacketQueue.Count > 0)
{
Packet pkt = thePacketQueue.Dequeue();
BeginSend(pkt, callback); // Actual code to send data over asynchronously
}
Task.Delay(1000); // <---- My question lies here
}
}
所有的锁都到位了!
我的问题是,当我使用Task.Delay
时,下一个周期是否可能由不同于当前周期的线程执行?
有没有其他方法,不用指定1秒的延迟,我可以使用类似ManualResetEvent
的东西,以及相应的代码是什么(我不知道如何使用ManualResetEvent
等
此外,我是async/await和TPL的新手,所以请耐心忍受我的无知。
TIA。
我的问题是,当我使用Task.Delay时,下一个周期是否可能由不同于当前周期的线程执行?
不使用您现有的代码,因为该代码有缺陷。它实际上根本不会在周期之间延迟。它创建一个将在一秒钟内完成的任务,但随后忽略该任务。您的代码应该为:
await Task.Delay(1000);
或潜在:
await Task.Delay(1000).ConfigureAwait(false);
对于第二段代码,它可以在不同的线程上运行每个循环。对于第一段代码,它将取决于同步上下文。如果您在具有线程亲和性的同步上下文中运行(例如,您从WPF或WinForms应用程序的UI线程调用该线程(,那么在延迟完成后,异步方法将在同一线程上继续。如果您在没有同步上下文的情况下运行,或者在不只是使用一个线程的同步上下文中运行,那么它可以在不同的线程中运行每个周期。
当您使用Task.Run
启动此代码时,您将不会有同步上下文,但值得注意的是,同一段代码在以不同方式运行时可能会有不同的行为。
顺便说一句,目前尚不清楚是什么在向thePacketQueue
添加项目,但除非是并发集合(例如ConcurrentQueue
(,否则您很可能也会遇到问题。