0

我正在尝试从控制台应用程序运行 Lambda 函数。这个想法是让它快速运行并忘记 lambda 函数,而无需等待 lambda 函数返回。我的代码似乎根本没有执行 lambda 函数。我知道该功能有效,因为我可以运行测试。当我运行下面的代码时,我只是得到一个任务取消异常。

var jsonSerializer = new JsonSerializer();
var lambdaConfig = new AmazonLambdaConfig() { RegionEndpoint = RegionEndpoint.USEast2 };
var lambdaClient = new AmazonLambdaClient(lambdaConfig);

using (var memoryStream = new MemoryStream())
{
    jsonSerializer.Serialize(myData, memoryStream);
    var lambdaRequest = new InvokeRequest
    {
        FunctionName = "MyFunction",
        InvocationType = "Event",
        PayloadStream = memoryStream
};

var result = Task.Run(async () => { return await lambdaClient.InvokeAsync(lambdaRequest); }).Result;

有人对我做错了什么有一些了解吗?

谢谢!

4

4 回答 4

4

myData如果数据是带双引号的有效 JSON,您可以直接传递您的数据而不是转换为 MemoryStream。

在函数名称中,您可以使用 ARN 或仅使用名称。在最新版本中,两者都适用于我AWSSDK.Lambda -Version 3.3.103.31

static readonly string awsAccessKey = "access key here";
static readonly string awsSecretKey = "secret key here";

private static BasicAWSCredentials awsCredentials = new BasicAWSCredentials(awsAccessKey, awsSecretKey);
private static AmazonLambdaConfig lambdaConfig = new AmazonLambdaConfig() { RegionEndpoint = RegionEndpoint.USEast1 };
private static AmazonLambdaClient lambdaClient = new AmazonLambdaClient(awsCredentials, lambdaConfig);

public async Task<string> GetLambdaResponse(string myData)
{
    var lambdaRequest = new InvokeRequest
    {
        FunctionName = "mylambdafunction",
        Payload = myData
    };

    var response = await lambdaClient.InvokeAsync(lambdaRequest);
    if (response != null)
    {
        using (var sr = new StreamReader(response.Payload))
        {
            return await sr.ReadToEndAsync();
        }
    }
    return string.Empty;        
}
于 2019-11-16T03:39:40.107 回答
2

Mixing blocking calls could be causing a deadlock. If the intent is to fire and for get then just call the desired function. Also why give request a stream only to dispose of it after wards

public static void Main(string[] args) {    
    var jsonSerializer = new JsonSerializer();
    var lambdaConfig = new AmazonLambdaConfig() { RegionEndpoint = RegionEndpoint.USEast2 };
    var lambdaClient = new AmazonLambdaClient(lambdaConfig);

    var memoryStream = new MemoryStream();

    jsonSerializer.Serialize(myData, memoryStream);
    var lambdaRequest = new InvokeRequest
    {
        FunctionName = "MyFunction",
        InvocationType = "Event",
        PayloadStream = memoryStream
    };

    lambdaClient.InvokeAsync(lambdaRequest);

    Console.ReadLine();
}
于 2018-08-04T14:52:47.283 回答
2

我相信您的代码中有两个问题:

  • (@Nikosi 提到)您在将 memoryStream 用于 lambda 调用之前对其进行处置
  • (在我的情况下有帮助的修复)当您将有效负载序列化到内存流中时,流中的位置指向其结束后的字节,因此 SDK 没有什么可以读取的。所以我只是用memoryStream.Seek(0L, SeekOrigin.Begin)

顺便说一句,假设这JsonSerializer是来自 Newtonsoft.Json 包的那个,我没有找到Serialize接受Stream参数的方法,只有TextWriteror JsonWriter。因此,可能有必要将其包装StreamWriter并确保您调用Flush或(或在使用内存流作为 Lambda 有效负载之前进行FlushAsync处置),如下所示:StreamWriter

await using var stream = new MemoryStream();
await using var streamWriter = new StreamWriter(stream);
var serializer = new JsonSerializer();
serializer.Serialize(streamWriter, payload);
await streamWriter.FlushAsync();
stream.Seek(0L, SeekOrigin.Begin);

log.LogInformation("Batch {0}: sending {1} messages to Lambda", batchId, batch.Count);

var lambdaResponse = await lambda.InvokeAsync(new InvokeRequest
{
    InvocationType = InvocationType.RequestResponse,
    PayloadStream = stream,
    //Payload = JsonConvert.SerializeObject(payload),
    FunctionName = lambdaArn
}, stoppingToken);
于 2020-09-01T21:24:14.303 回答
1

Nkosi 的答案中的 FunctionName 实际上应该是您的 lambda 函数的整个 ARN,因此请从 Nkosi 的答案中获取:

public static void Main(string[] args) {    
var jsonSerializer = new JsonSerializer();
var lambdaConfig = new AmazonLambdaConfig() { RegionEndpoint = RegionEndpoint.USEast2 };
var lambdaClient = new AmazonLambdaClient(lambdaConfig);

var memoryStream = new MemoryStream();

jsonSerializer.Serialize(myData, memoryStream);
var lambdaRequest = new InvokeRequest
{
    FunctionName = "arn:aws:lambda:ap-southeast-2:{id}:function:MyFunction",
    InvocationType = "Event",
    PayloadStream = memoryStream
};

lambdaClient.InvokeAsync(lambdaRequest);

Console.ReadLine();
于 2019-02-12T04:47:28.823 回答