Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/329.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
在无服务器环境中,C#async/await有什么好处?_C#_Async Await_Aws Lambda - Fatal编程技术网

在无服务器环境中,C#async/await有什么好处?

在无服务器环境中,C#async/await有什么好处?,c#,async-await,aws-lambda,C#,Async Await,Aws Lambda,对于只调用外部服务或写入数据存储的微服务功能,在C#中使用async/await有什么意义吗 我们在AWS Lambdas中编写了很多这样的代码,很难确定async/await在这种情况下的实际收益是什么,或者它到底在哪里有用。对于更传统的IIS web服务,异步释放操作系统中的线程,并允许服务器服务更多请求 但对于AWS Lambdas,函数每次执行仅处理一个请求(限制为1000次同时执行)。因此,如果我们有一个长时间运行的外部进程或具有显著延迟的外部依赖项,那么每个函数的执行都将被挂起,直到

对于只调用外部服务或写入数据存储的微服务功能,在C#中使用async/await有什么意义吗

我们在AWS Lambdas中编写了很多这样的代码,很难确定async/await在这种情况下的实际收益是什么,或者它到底在哪里有用。对于更传统的IIS web服务,异步释放操作系统中的线程,并允许服务器服务更多请求

但对于AWS Lambdas,函数每次执行仅处理一个请求(限制为1000次同时执行)。因此,如果我们有一个长时间运行的外部进程或具有显著延迟的外部依赖项,那么每个函数的执行都将被挂起,直到外部进程完成(假设Lambda是同步调用的)

这里是一个具有三个处理程序的示例Lambda,我将其中的第三个放在一个单独的Lambda中,称为“DavidSleep”,它只是表示一个长期运行的外部依赖项。当我使用前两个处理程序中的任何一个调用另一个名为“DavidTest”的Lambda时,我发现async/await版本与缺少async/await的版本在功能或性能上没有区别。这两个函数都需要多个并发Lambda执行,并且需要相同的时间

因此,异步版本似乎与无异步版本没有区别,但有区别吗

public class Test
{
    private IAmazonLambda lambda;

    public Test()
    {
        lambda = new AmazonLambdaClient();
    }

    [LambdaSerializer(typeof(JsonSerializer))]
    public async Task HandleAsync(Request request)
    {
        Console.WriteLine($"Executing for { request.Name }");
        await lambda.InvokeAsync(new InvokeRequest
        {
            FunctionName = "DavidSleep",
            InvocationType = InvocationType.RequestResponse,
            Payload = JsonConvert.SerializeObject(request)
        });
    }

    [LambdaSerializer(typeof(JsonSerializer))]
    public void Handle(Request request)
    {
        Console.WriteLine($"Executing for { request.Name }");
        lambda.InvokeAsync(new InvokeRequest
        {
            FunctionName = "DavidSleep",
            InvocationType = InvocationType.RequestResponse,
            Payload = JsonConvert.SerializeObject(request)
        }).Wait();
    }

    [LambdaSerializer(typeof(JsonSerializer))]
    public void Sleep(Request request)
    {
        Console.WriteLine($"{ request.Name }{ request.RequestId } begin");
        Thread.Sleep(request.WaitInSeconds * 1000);
        Console.WriteLine($"{ request.Name }{ request.RequestId } end");
    }
}

在无服务器上下文中使用async/await的好处仍然是,您可以控制调用线程,释放另一个调用方来使用该线程。我不知道AWS是否会从1000次呼叫限制中删除
wait
呼叫,但他们可能会

对于这些一行程序样式的任务调用,在方法中没有其他异步调用,您可以简单地返回任务。无论AWS Lambda 1000调用限制如何,标记方法
async
和调用
wait
都会增加不必要的开销

例如:

[LambdaSerializer(typeof(JsonSerializer))]
公共任务HandleAsync(请求)
{
WriteLine($“为{request.Name}执行”);
返回lambda.InvokeAsync(新的InvokeRequest
{
FunctionName=“DavidSleep”,
InvocationType=InvocationType.RequestResponse,
Payload=JsonConvert.SerializeObject(请求)
});
}

这里讨论了两种情况:

  • Lambda函数中使用的C#代码中的异步等待
  • 异步调用与同步调用长时间运行的lambda函数
Lambda函数中C#代码的异步/等待模式
Lambda执行框架并不关心代码是如何执行的——它只是调用.Net框架来执行代码并等待执行完成。在函数内部,这是通常的异步/等待模式优势

如果以异步方式启动长操作,然后使用主线程执行不依赖于长操作结果的不同操作,那么C#代码中的Async/await非常有用。如果函数中有一个长操作,则异步和同步执行是相似的。使用异步优于同步没有任何好处(事实上,正如上面的评论所指出的,使用异步机制可能会有一些开销)

异步或同步调用lambda函数
这个问题描述了这种差异的一个例子——使用异步方法和同步方法调用长时间运行的lambda。由于正当理由,未观察到任何变化

同样,只有当主线程可以执行不同的操作而不依赖于异步方法的结果时,异步调用才是有益的。该示例仅显示对lambda的调用。因此,在异步和同步情况下,主线程都必须等待其执行完成。它没有将等待时间用于其他执行,因此执行所用的总时间没有差异

异步方案
假设有两个lambda函数,DavidSleep和JohnSleep,它们需要相互独立地并行调用。DavidSleep需要1秒执行,JohnSleep需要2秒执行

如果在上面的HandleAsync()中调用这两个函数,则总执行时间将为~2秒(加上几毫秒的异步开销)

如果在上面的Handle()中调用这些函数,那么总的执行时间将是~3秒(加上几毫秒)

当您需要执行多个进程时,使用异步/等待可以工作,并且使进程忙碌的事情(例如线程等)。此外,您可以让它等待,按照您想要的顺序按自己的方式执行,并错开多个执行。

异步和等待很容易使用,但很难理解。经过10多年的C语言编程,我仍然无法理解每一个涉及的机械师。让我只提两件事:
Task.Wait、Task.Run、BlockingCollection、lock语句、configurewait、CancellationToken、TaskCompletionSource等

因此,除非您只与高级C#程序员打交道,而且您也是其中之一,否则我将尽可能避免使用async/Wait。有一条规则,你不应该过早地优化你的代码。如果您需要某个结果,async/await无论如何也帮不了您,因为只要您请求结果,您仍然会被阻止。但是,您可以通过在后台线程中运行async/await来推迟获得结果

我正在同步编写所有代码。如果我阻止我的UI,那么我知道我可以使用async/await来避免它,因为UI希望我这样做。但是UI直到最终处理后才显示结果。这就是为什么我说我被封锁了。仅仅因为该行可能在调试器中执行,并不意味着结果将实际出现在UI中

当我识别一个c