如何为 lambda 表达式提供一次变量值?
How can I provide a variable value to a lambda expression exactly once?
我正在尝试使用 Polly 库来 monitor/restart 失败的任务。但是,我很难在重试之间保持相同的输入参数。
using System;
using System.IO;
using System.Collections.Generic;
using Polly;
using System.Threading.Tasks;
namespace Sampler
{
class Program
{
public static async Task Main(string[] args)
{
// create and execute policies for each sampler
List<Task> policy_list = new List<Task>();
for(int i = 0; i < 2; i++)
{
var policy = Policy
.Handle<Exception>()
.RetryForeverAsync()
.ExecuteAsync(async () => await Program.TaskMethod(i.ToString()));
policy_list.Add(policy);
}
await Task.WhenAll(policy_list.ToArray());
Console.WriteLine("Press any key to exit...");
Console.ReadLine();
}
public static async Task TaskMethod(string task_id)
{
Console.WriteLine("Starting Task {0}", task_id);
while (true)
{
await Task.Delay(5000);
Console.WriteLine("Hello from task {0}", task_id);
int i = 0;
int b = 32 / i;
}
}
}
}
当我 运行 这段代码时,我得到以下输出:
Starting Task 0
Starting Task 1
Hello from task 1
Hello from task 0
Starting Task 2 // BAD! this should be starting task 0
Starting Task 2 // BAD! this should be starting task 1
Hello from task 2
Hello from task 2
Starting Task 2
Starting Task 2
明显的问题与此行相关:.ExecuteAsync(async () => await Program.TaskMethod(i.ToString()));
我将任务编号作为变量提供,这是一个问题,因为此变量在 for 循环结束时变为“2”。因此,任务 ID 2 用于剩余的重试。
所以我的问题是:如何重新格式化我的 lambda 表达式,使其只引用 'i' 变量一次,从而保持其原始任务 ID?
这叫做闭包。临时局部变量中的安全 i
:
for(int i = 0; i < 2; i++)
{
int temp = i;
var policy = Policy
.Handle<Exception>()
.RetryForeverAsync()
.ExecuteAsync(async () => await Program.TaskMethod(temp.ToString()));
policy_list.Add(policy);
}
这里有一个 nice article 解释得比我在这里所能解释的要好得多。
我正在尝试使用 Polly 库来 monitor/restart 失败的任务。但是,我很难在重试之间保持相同的输入参数。
using System;
using System.IO;
using System.Collections.Generic;
using Polly;
using System.Threading.Tasks;
namespace Sampler
{
class Program
{
public static async Task Main(string[] args)
{
// create and execute policies for each sampler
List<Task> policy_list = new List<Task>();
for(int i = 0; i < 2; i++)
{
var policy = Policy
.Handle<Exception>()
.RetryForeverAsync()
.ExecuteAsync(async () => await Program.TaskMethod(i.ToString()));
policy_list.Add(policy);
}
await Task.WhenAll(policy_list.ToArray());
Console.WriteLine("Press any key to exit...");
Console.ReadLine();
}
public static async Task TaskMethod(string task_id)
{
Console.WriteLine("Starting Task {0}", task_id);
while (true)
{
await Task.Delay(5000);
Console.WriteLine("Hello from task {0}", task_id);
int i = 0;
int b = 32 / i;
}
}
}
}
当我 运行 这段代码时,我得到以下输出:
Starting Task 0
Starting Task 1
Hello from task 1
Hello from task 0
Starting Task 2 // BAD! this should be starting task 0
Starting Task 2 // BAD! this should be starting task 1
Hello from task 2
Hello from task 2
Starting Task 2
Starting Task 2
明显的问题与此行相关:.ExecuteAsync(async () => await Program.TaskMethod(i.ToString()));
我将任务编号作为变量提供,这是一个问题,因为此变量在 for 循环结束时变为“2”。因此,任务 ID 2 用于剩余的重试。
所以我的问题是:如何重新格式化我的 lambda 表达式,使其只引用 'i' 变量一次,从而保持其原始任务 ID?
这叫做闭包。临时局部变量中的安全 i
:
for(int i = 0; i < 2; i++)
{
int temp = i;
var policy = Policy
.Handle<Exception>()
.RetryForeverAsync()
.ExecuteAsync(async () => await Program.TaskMethod(temp.ToString()));
policy_list.Add(policy);
}
这里有一个 nice article 解释得比我在这里所能解释的要好得多。