c# – 如何衡量等待异步操作的性能?

我有一个从多个MessageQueue实例读取的 Windows服务.这些消息队列都运行自己的任务来读取消息.通常,在阅读消息后,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()可以使用已发布的线程进行处理.

解决方法

使用async-await不会加快执行单个操作所需的时间,它只是意味着您没有一个线程在等待什么都不做.

在你的情况下,Task.Delay将花费一秒钟,无论如何,但在这里:

Task.Delay(1000).Wait();

你有一个线程,在这里等待第二个结束:

await Task.Delay(1000);

你没有.您仍在异步等待(因此,等待),但没有使用线程,这意味着更好的可伸缩性.

在async-await中,您可以获得性能提升,因为您的应用程序可以使用更少的线程执行相同操作,或者使用相同的线程执行更多操作.要衡量您需要同时进行大量异步操作.只有这样,您才会注意到async选项比同步选项更好地利用cpu资源.

有关解冻螺纹的更多信息,请访问There Is No Thread

相关文章

在项目中使用SharpZipLib压缩文件夹的时候,遇到如果目录较深,则压缩包中的文件夹同样比较深的问题。比...
项目需要,几十万张照片需要计算出每个照片的特征值(调用C++编写的DLL)。 业务流程:选择照片...
var array = new byte[4]; var i = Encoding.UTF8.GetBytes(100.ToString(&quot;x2&quot;));//...
其实很简单,因为Combox的Item是一个K/V的object,那么就可以把它的items转换成IEnumerable&lt;Dic...
把.net4.6安装包打包进安装程序。 关键脚本如下: 头部引用字符串对比库 !include &quot;WordFunc....
项目需求(Winform)可以批量打印某个模板,经过百度和摸索,使用iTextSharp+ZXing.NetʿreeSp...