У меня есть цикл, который создает таймеры. У меня с этим 2 проблемы.
Первая проблема заключается в том, как выполнить команду как «запустить и забыть», чтобы я мог ее вызвать, и она будет выполняться сама по себе в другом потоке, и сама отправит сообщение в API. Это тот случай, если для свойства refresh установлено значение 0.
Во-вторых, параметр в цикле (check.key) заменяется на следующей итерации цикла. Когда делегат запускает метод, ему передается замененное значение, а не назначенное оригинал !!!
В приведенном ниже примере значения назначены правильно, но когда делегат срабатывает, он всегда срабатывает с параметром "3".
Словарь _mydict заполнен данными из удаленного API.
Classtocall и methodtocall не всегда будут одинаковыми. Их можно вызывать более одного раза - так как предоставленный ключ предоставляет доступ к большему количеству параметров в классе Test. Свойство refresh в классе Test определяет время таймера.
Надеюсь, это имеет смысл!
Код (быстрый макет, так как мой настоящий код большой):
public class Test
{
public string ClassToCall;
public string MethodToCall;
public string UniqueKey;
public long Refresh;
// more but removed for sample
public Test(string MyClass, string MyMethod, string Key)
{
this.ClassToCall = MyClass;
this.MethodToCall = MyMethod;
this.UniqueKey = Key;
}
}
class runme
{
public static void runmefirst(string Key)
{// Does some processing based on Key
}
public static void runmesecond(string Key)
{ // Does some processing based on Key
}
public static void runmelast(string Key)
{ // Does some processing based on Key
}
}
class myclass
{
private static Timer[] timers;
static void Main()
{
Dictionary<string, Test> _mydict = new Dictionary<string, Test>();
_mydict.Add("1", new Test("runme", "runmefirst", "1"));
_mydict.Add("2", new Test("runme", "runmesecond", "2"));
_mydict.Add("3", new Test("runme", "runmelast", "3"));
int i = 0;
foreach (KeyValuePair<string,Test> check in _mydict)
{
Type t = Type.GetType(check.Value.ClassToCall);
if (t != null)
{
MethodInfo mi = t.GetMethod(check.Value.MethodToCall);
if (mi != null)
{
if (check.Value.Refresh == 0)
{
mi.Invoke(null, new string[] { check.Key }); // << problem 1: need this fire and forget!
}
else
{
myclass.timers[i] = new Timer(
delegate { mi.Invoke(null, new string[] { check.Key }); }, // << problem 2: when called, check.Key is always last value in loop
null,
i * 1000,
check.Value.Refresh * 5000
);
}
}
}
i+=1;
}
}
}
Спасибо