为什么异步函数调用两次? [英] Why async functions are called twice?

查看:207
本文介绍了为什么异步函数调用两次?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我使用线程计时器做一些定期的工作:

I'm using Threading timer to do some periodic job:

private static async void TimerCallback(object state)
{
        if (Interlocked.CompareExchange(ref currentlyRunningTasksCount, 1, 0) != 0)
        {
            return;
        }

        var tasksRead = Enumerable.Range(3, 35).Select(i => ReadSensorsAsync(i));
        await Task.WhenAll(tasksRead);
        var tasksRecord = tasksRead.Where(x => x.Result != null).Select(x => RecordReadingAsync(x.Result));
        await Task.WhenAll(tasksRecord);

        Interlocked.Decrement(ref currentlyRunningTasksCount);
}

我做了计时器回调异步和使用 WhenAll 。在每个工作异步函数我有一个控制台输出,这说明活动。现在的问题是,在第二计时器事件每个异步函数出于某种原因工作两次。该定时器被设置为长的时间。该应用程序是Windows控制台类型。它是选择,不知怎的,使其运行两次?

I made timer call back async and used WhenAll. In each working async function I have one Console output, which shows activity. Now the problem is that on second timer event each async function is working twice for some reason. The timer is set to long period. The application is Windows Console type. Is it Select that somehow make it run twice?

推荐答案

var tasksRead = Enumerable.Range(3, 35).Select(i => ReadSensorsAsync(i));

创建一个懒洋洋地评估了IEnumerable它映射到数字方法调用的结果。 ReadSensorsAsync 这里没有调用时,它的将会的被评估时调用。

creates a lazily evaluated IEnumerable which maps numbers to method invocation results. ReadSensorsAsync is not invoked here, it will be invoked during evaluation.

这IEnumerable的是两次评估。这里:

This IEnumerable is evaluated twice. Here:

await Task.WhenAll(tasksRead);

在这里:

// Here, another lazy IEnumerable is created based on tasksRead.
var tasksRecord = tasksRead.Where(...).Select(...);  
await Task.WhenAll(tasksRecord);  // Here, it is evaluated.

因此​​, ReadSensorsAsync 被调用两次。

由于csharpfolk的意见建议,物化了IEnumerable应该解决这个问题:

As csharpfolk suggested in the comments, materializing the IEnumerable should fix this:

var tasksRead = Enumerable.Range(3, 35).Select(i => ReadSensorsAsync(i)).ToList();

这篇关于为什么异步函数调用两次?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆