【发布时间】:2014-06-15 02:32:16
【问题描述】:
我有一个从多个 MessageQueue 实例读取的 Windows 服务。这些消息队列都运行自己的Task 来读取消息。通常,在阅读完一条消息后,I/O 数据库的工作就完成了。我发现一些文章声称在 I/O 操作上使用异步是个好主意,因为它会释放线程。我正在尝试模拟在控制台应用程序中使用异步 I/O 操作的性能提升。
控制台应用程序
在我的测试环境中,我有 10 个队列。 GetQueues() 返回 10 个不同的 MessageQueue 实例。
static void Main(string[] args)
{
var isAsync = Console.ReadLine() == "Y";
foreach (var queue in queueManager.GetQueues())
{
var temp = queue;
Task.Run(() => ReceiveMessagesForQueue(temp, isAsync));
}
while (true)
{
FillAllQueuesWithMessages();
ResetAndStartStopWatch();
while(!AllMessagesRead())
{
Thread.Sleep(10);
}
Console.WriteLine("All messages read in {0}ms", stopWatch.ElapsedMilliseconds);
}
}
static async Task ReceiveMessagesForQueue(MessageQueue queue, bool isAsync)
{
while (true)
{
var message = await Task.Factory.FromAsync<Message>(queue.BeginReceive(), queue.EndReceive);
if (isAsync)
await ProcessMessageAsync(message);
else
ProcessMessage(message);
}
}
异步消息处理
在 Task.Delay() 上使用 await,所以应该释放当前的 Thread
static async Task ProcessMessageAsync(Message message)
{
await Task.Delay(1000);
BurnCpu();
}
同步消息处理
等待Task.Delay(),所以不应该释放当前的Thread
static void ProcessMessage(Message message)
{
Task.Delay(1000).Wait();
BurnCpu();
}
最终,结果是平等的。我在这里遗漏了什么吗?
编辑 1
我正在使用stopWatch.ElapsedMilliseconds 测量总时间。我使用 FillAllQueuesWithMessages() 填充所有队列,其中包含 10、100、10000 条或更多消息。
编辑 2
ReceiveMessagesForQueue() 现在返回 Task 而不是 void。
编辑 3(修复)
这个测试确实显示了我现在的性能改进。我不得不让BurnCpu() 花费更多时间。在等待Task.Delay() 时,BurnCPU() 可以使用释放的线程进行处理。
【问题讨论】:
标签: c# task-parallel-library async-await performance-testing c#-5.0