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);
这允许所有任务并行触发,但暂停进一步执行直到它们全部完成,确保在进程终止之前完成任务。
我有一个 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);
这允许所有任务并行触发,但暂停进一步执行直到它们全部完成,确保在进程终止之前完成任务。