C# 中的 Fire and Forget 多个方法

Fire and Forget multiple methods in C#

我有一个 Azure 函数,它能够调用多个 API 个端点,而无需等待其中任何一个的结果。

Azure 函数在计时器触发器上运行,每 10 秒运行一次。

我所有的 API 调用和调用它们的参数都存储在 SQL table 中。我想确保在不等待特定调用完成的情况下进行 API 调用。

这只是我将要做的事情的蓝图。

[FunctionName("FunctionScheduler")]
public static async Task RunAsync([TimerTrigger("*/10 * * * * *")]TimerInfo myTimer, ILogger log)
{
    log.LogInformation("FUNCTION SCHEDULER STARTING ..");

    log.LogInformation($"C# Timer trigger function executed at: {DateTime.Now}");

    for(int i=0; i < 20; i++)
    {
        var task = Task.Run(() => ApiRef1(i, log));
        var taskref = await task;
    }

}

目前 ApiRef1() 只是打印出变量 i 的值。我得到打印数字 0 到 19 的预期输出。我想要并行执行 ApiRef1() 方法,该方法最终将被如下所示的方法替换。

private static void CallApi(string apiName, string apiEndpoint, string methodType, string authenticationType, IDictionary<int, string> parameters, ILogger log)
{
    try
    {
        log.LogInformation($"Call to API {apiName} started.." );

        // Call API
    }
    catch (Exception ex)
    {
        log.LogInformation($"Exception {ex.Message} occurred.." );
    }
}

是否有更好的方法或此方法有效?

Task.Run()returns一个Task。当你 "fire and forget" 时,你不关心那个任务。

要采纳 建议的内容,请使用弃牌以确保您不关心结果。

public void Run()
{
    ...

    _ = Task.Run(() => ApiRef1(i, log));

    ...
}

包含 Task.Run 调用的方法本身不是异步的。除非您有其他使用 await 的方法调用,否则您不再需要异步。

您可以使用 async/Task 功能。这是一个例子

    public static class AzureFunction
    {
        [FunctionName("SomeAzureFunction")]
        public static void Run([TimerTrigger("*/10 * * * * *")]TimerInfo myTimer, ILogger log)
        {
            Function1(log);
            Function2(log);
            Function3(log);
        }

        private static async void Function1(ILogger log)
        {
            await Task.Run(() =>
            {
                Thread.Sleep(6000);
                log.LogInformation("Function 1 now executed");
            });
        }

        private static async void Function2(ILogger log)
        {
            await Task.Run(() =>
            {
                Thread.Sleep(2000);
                log.LogInformation("Function 2 now executed");
            });
        }

        private static async void Function3(ILogger log)
        {
            await Task.Run(() =>
            {
                log.LogInformation("Function 3 now executed");
            });
        }
    }

(Threat.Sleep() 行只是为了向您展示 how/that 函数是相互独立执行的)

在输出中 window 你会看到所有三个函数都启动了,但是函数 3 会先完成(因为我们没有让线程休眠),然后函数 2 会完成(因为我们有一个 2秒延迟),最后功能 1 将完成(延迟 6 秒)。

请注意,此示例中的所有函数都有一个 return 类型 "Void"。因此,此示例仅在您不关心函数中的任何 return 值时才有效。

但我认为这接近您的要求

当您使用 Azure 函数时,您不能一蹴而就,因为您冒着函数在所有任务完成之前终止的风险。

但是,我们不关心任务的结果,所以我们不需要单独等待每个任务。

System.Collections.Generic.List<System.Threading.Tasks.Task> tasks = new System.Collections.Generic.List<System.Threading.Tasks.Task>();
for (int i = 0; i < 20; i++)
{
  tasks.Add(System.Threading.Tasks.Task.Run(() => ApiRef1(i, log));
}
await System.Threading.Tasks.Task.WhenAll(tasks);

这允许所有任务并行触发,但暂停进一步执行直到它们全部完成,确保在进程终止之前完成任务。