在C#中调用AWS Lambda函数

时间:2018-08-04 14:29:37

标签: c# amazon-web-services aws-lambda fire-and-forget

我正在尝试从控制台应用程序运行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 个答案:

答案 0 :(得分:2)

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

  • (由@Nikosi提及),在将memoryStream用于lambda调用之前,请先对其进行处置
  • (对我而言,此修复程序很有帮助)将有效负载序列化为内存流时,流中的位置指向其末尾的字节,因此SDK无法读取任何内容。所以我只用了memoryStream.Seek(0L, SeekOrigin.Begin)

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

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);

答案 1 :(得分:0)

混合阻止呼叫可能会导致死锁。如果目的是触发并获取,则只需调用所需的函数。还要为什么只给请求流分配一个病房后处理

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();
}

答案 2 :(得分:0)

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

select * from (select cosine_distance(feature,?) as d from test_table order by d) nt 
where nt.d>? 
order by nt.d desc limit ?

答案 3 :(得分:0)

如果数据是带双引号的有效JSON,则可以直接传递myData而不是转换为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;        
}