2013-11-20 6 views
0

Я хочу передать переменную в функцию, которая запускается после задержки. Я видел аналогичный вопрос о том, как это сделать (см. Ниже). Я не думаю, что это то, что я хочу, так как каждый раз, когда вызывается method1, растет число прикрепленных анонимных функций? Что мне нужно сделать, это удалить любую существующую прикрепленную анонимную функцию перед добавлением нового. Но я не думаю, что это возможно. Есть ли способ вызвать метод после задержки, но каждый раз передавать новое значение переменной?Вызвать метод (с аргументом) после задержки

using System.Timers; 

myTimer = new Timer(); 
myTimer.Interval = 3000; 
myTimer.AutoReset = false; 

public void method1(int var1){ 
    myTimer.Elapsed += delegate { doSomething(var1); }; 
    myTimer.Start(); 
} 

public void doSomething(int arg1){...} 

UPDATE

В основном всякий раз, когда method1 запускается, я хочу что-то должно произойти 3 секунд позже, и мне нужно передать в качестве аргумента, который может изменяться каждый раз.

Я не думаю, что могу использовать поле для хранения переменной, потому что method1 может вызываться несколько раз до истечения первого таймера. То есть может быть несколько человек. Например. в один момент времени дия из «DoSomething» откладывание случиться может быть ...

doSomething(3) 
doSomething(7) 
doSomething(1) 

Он используется только в тестбенче и method1 будет выполняться называется не более чем в 50 раз. Я хочу обеспечить, чтобы каждый doSomething(var1) вызывался один раз, а не каждые 3 секунды. Т.е. каждый раз вызывается doSomething, вызываемый при вызове method1.

Это приложение для Windows.

+0

Почему не вы перемещаете свой параметр в поле и используете его как общий ресурс? – Redwan

+0

@ Redwan, не могу этого сделать, я обновляю свой вопрос. – spiderplant0

+0

Какие данные находятся в переменной?Вы хотите каждый раз выполнять одну и ту же логику против разных данных или, возможно, выполнять другую логику? – LeftyCoder

ответ

3

Нет никакого хорошего способа сделать это, используя System.Timers.Timer.

С помощью System.Threading.Timer вы можете передать объект userState в конструктор. Затем этот объект передается на обратный вызов таймера с каждым тиком. Например:

string Whatever = "foo"; 
System.Threading.Timer timer = 
    new System.Threading.Timer(MyTimerCallback, whatever, 100, 100); 

void MyTimerCallback (object state) 
{ 
    string theData = (string)state; 
    // at this point, theData is a reference to the "Whatever" string. 
    // do tick processing 
} 

Вы можете, если вы хотите продлить System.Timers.Timer и добавить свойство для хранения данных. Что-то вроде:

class DerivedTimer : System.Timers.Timer 
{ 
    public string Foo { get; set; } 
} 

myTimer = new DerivedTimer(); 
myTimer.Interval = 3000; 

public void methodRunRegularly(int var1){ 
    myTimer.Foo = "Foobar!"; 
    myTimer.Elapsed += doSomething; 
    myTimer.Start(); 
} 

public void doSomething(object sender, EventArgs e) 
{ 
    var t = (DerivedTimer)sender; 
    var foo = t.Foo; 
    // do processing 
} 

Ссылка на таймер передается в параметре sender. Вы можете просто записать это, а затем указать свойство Foo, которое вы установили при инициализации таймера.

3

В этом случае используются реактивные расширения (используйте пакет nuget «rx-main»).

Выполнить метод с секундной задержкой 3:

public void method1(int value) 
{ 
    ThreadPoolScheduler.Instance.Schedule(
     TimeSpan.FromSeconds(3),() => doSomething(value)); 
} 

Это примерно так же коротким, как он получает!

5

Использование TPL (& .Net 4.5), вы можете сделать что-то вроде этого:

public static class ActionExtensions 
{ 
    public static async void DelayFor(this Action act, TimeSpan delay) 
    { 
     await Task.Delay(delay); 
     act(); 
    } 
} 

//usage 
Action toDo =() => doSomething(var1); 
toDo.DelayFor(TimeSpan.FromSeconds(3)); 

... или это может быть проще для вашего приложения:

static async void DoSomethingLater(int n) 
{ 
    await Task.Delay(TimeSpan.FromSeconds(3)); 
    //DoSomething(n); 
} 

//usage 
void Method1(int n) 
{ 
    DoSomethingLater(n); 
} 
+0

О да! Я еще не «запекался» в «Task.Delay» ... хороший. async * void * хотя? : О! Still + 1 –

+0

Да, у меня недостаточно контекста, но похоже, что 'Method1' - обработчик событий и' async void' _should_ будет в порядке. –

Смежные вопросы