【问题标题】:C# InvokeAsync in foreach only invoking Lambda one timeforeach 中的 C# InvokeAsync 仅调用 Lambda 一次
【发布时间】:2021-05-23 00:03:25
【问题描述】:

我在 C# 中有一个带有简单 foreach 循环的 lambda。 foreach 循环为 List 中的每个项目调用一个 python lambda..

foreach (NOAAQInfo noaaqInfo in batchItemsForMyPython)
{
    Console.WriteLine($"invoking MyPython api for: {noaaqInfo.Email}");

    Task<NOAAQInfo> t = SendToMyPython.executeLambda(dbLogic, noaaqInfo, context);
    Task tCleanup = t.ContinueWith((antecedent) =>
    {
        Console.WriteLine($"MyPython success: {antecedent.Result.Email}");
    });
}

这是实际调用 Python Lambda 的函数。

internal static async Task<NOAAQInfo> executeLambda(DBLogic dbLogic, NOAAQInfo noaaqInfo, ILambdaContext context)
{
    AmazonLambdaClient amazonLambdaClient = new AmazonLambdaClient();

    NOAAQInfo noaaqInfoResult = null;

    InvokeRequest request = new InvokeRequest()
    {
        FunctionName = MyPython,
        Payload = JsonConvert.SerializeObject(payload)
    };


    CancellationToken cancellationToken = new CancellationToken();
    string messageStr = null;
    InvokeResponse invokeResponse = null;

    invokeResponse = await amazonLambdaClient.InvokeAsync(request, cancellationToken);

    if (invokeResponse.StatusCode == (int)HttpStatusCode.OK)
    {
        if (resp.body != VerifiedStrResponse)
        {
            noaaqInfoResult = noaaqInfo;
        }
    }

    return noaaqInfoResult;
}

如果我查看 C# lambda 的日志,我可以看到被发送到 python lambda 的 2 个项目:

2021-02-19T14:04:39.837-08:00   invoking MyPython api for: testAAA@GMAIL.COM
2021-02-19T14:04:40.057-08:00   invoking MyPython api for: testBBB@GMAIL.COM

但是,当我查看 Python lambda 日志时,我只看到收到了一项:

[INFO]  2021-02-19T14:04:40.837-08:00Z  adafecd6-8f32-4b7f-8d46-94465ac03a63    received params:{'Email': 'testAAA@GMAIL.COM'}

为什么我在 python 日志中没有看到 testBBB?即应该有 2 次 python lambda 调用。

我还仔细检查了没有额外的日志流,并且 python lambda 没有设置任何并发限制。

在这个问题上真的让我摸不着头脑,因为我没有收到任何错误。只是只有一个项目被发送到 python lambda。

此外,ContinueWith() 中的日志记录行也没有显示。

【问题讨论】:

标签: c# .net amazon-web-services aws-lambda


【解决方案1】:

你错过了一些等待。

我相信这对你有用:

var noaaqInfos = batchItemsForMyPython.Select(async noaaqInfo => {
  Console.WriteLine($"invoking MyPython api for: {noaaqInfo.Email}");
  var t = await SendToMyPython.executeLambda(dbLogic, noaaqInfo, context);
  Console.WriteLine($"MyPython success: {t.Result.Email}");
  return t;
});
Task.WhenAll(noaaqInfos);

如果您将控制台内容移到异步方法中,删除您似乎没有使用的 DbLogic 和 ILambdaContext 也会容易得多,然后调用就变成了:

var tasks = batchItemsForPython.Select(SendToMyPython.executeLambda);
Task.WhenAll(tasks);

【讨论】:

  • 谢谢@Robert McKee,你能解释一下 awaits 的帮助吗?
  • 您必须等待异步方法。您的问题是您正在触发事件,但从未等待结果,因此程序将结束。有点像如果我告诉你“数到 100”,然后立即阻止你。在我打断你并让你停下来之前,你可能已经可以说“1”,或者可能不会。它比这要复杂一些,特别是因为异步不是多线程,但在一个非常简单的层面上就是这样。
  • 我假设您实际上希望 python 方法同时运行,而不是一次运行一个。如果您希望它们一次运行一个,只需在此处添加等待:NOAAQInfo t =await SendToMyPython.executeLambda(dbLogic, noaaqInfo, context); 并在之后摆脱 continue 的东西,然后只是 console.write。
  • 很好的比喻!打算试试你的解决方案
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2012-06-22
  • 2017-04-11
  • 2018-12-17
  • 1970-01-01
  • 2011-05-16
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多