2012-04-02 17 views
20

だから私はC#でを.Net 4に使用しています。オブジェクトをタイマーイベントに渡すにはどうすればよいですか?

私はそうのように私のタイマーオブジェクトを持っている:

var timer = new Timer {Interval = 123}; 

私は私のタイマー経過イベントハンドラはそうのような方法で指摘している:

timer.Elapsed += MyElapsedMethod; 

そして、私の方法は、このようになります

static void MyElapsedMethod(object sender, ElapsedEventArgs e) 
{ 
    Console.WriteLine("Foo Bar"); 
} 

このメソッドに文字列を渡したいのですが、どうすればいいですか?

おかげ

答えて

48

これを行う最も簡単な方法は、匿名関数にイベントハンドラを変更することです。宣言のポイントで文字列を渡すことができます。

string theString = ...; 
timer.Elapsed += (sender, e) => MyElapsedMethod(sender, e, theString); 

static void MyElapsedMethod(object sender, ElapsedEventArgs e, string theString) { 
    ... 
} 
+2

実際には、まだいくつかのグローバル変数を読んでいます(はい、ローカルかもしれませんが、意味をなさない)。イベントハンドラを無名関数に置き換えました。 this 'timer.Elapsed + =(s、e)=> Console.WriteLine(theString);'さらに短く、アイデアは同じです。 –

+0

イベントハンドラをインラインに割り当てるのは、後でリリースできないため、お勧めしません。 –

2

あなたは、いくつかのオブジェクト内の文字列を保存し、イベントハンドラでそれを読むことができます:

static string _value; 

static void MyElapsedMethod(object sender, ElapsedEventArgs e) 
{ 
    Console.WriteLine(_value); 
} 

UPDATE:異なる構文を経由して同じコード: timer.Elapsed += (s,e) => Console.WriteLine(_value);

UPDATE:システムを使用しても、考えてみましょう.Treader.Timer代わりに

State state = new State(); 
Timer timer = new Timer(OnTimer, state, 0, 123); 
state.Value = "FooBar"; // change state object 

あなたは、タイマーコールバックの状態を取得することができます。

static void OnTimer(object obj) 
{ 
    State state = obj as State; 
    if (state == null) 
     return;   

    Console.WriteLine(state.Value); 
} 
+0

これは私がやっていたことです、私はより直接的なルートを探していました! – JMK

0

好きな文字列を保持し、その後の経過イベントハンドラで、それを取得するために、同じクラスのフィールドを使用します。しかし、クロススレッドの問題については注意が必要です。

12

"Elapsed"イベントハンドラの登録をやり直したい場合は、変数内で覚えていない状態でデリゲートを使用しないでください。

もう1つの解決策は、Timerに基づいてカスタムクラスを作成することです。ちょうどあなたが好きなメンバーを追加し、「経過」イベントハンドラの「差出人」引数からバックカスタムTimerオブジェクトを取得します:

class CustomTimer : System.Timers.Timer 
{ 
    public string Data; 
} 

private void StartTimer() 
{ 
    var timer = new CustomTimer 
    { 
     Interval = 3000, 
     Data = "Foo Bar" 
    }; 

    timer.Elapsed += timer_Elapsed; 
    timer.Start(); 
} 

void timer_Elapsed(object sender, ElapsedEventArgs e) 
{ 
    string data = ((CustomTimer)sender).Data; 
} 

もちろんこの戦略は、限り、あまりにも他のイベントとクラスのために働きます基本クラスは封印されていません。

0
Timer aTimer = new Timer(300); 
       aTimer.Elapsed += delegate { PublishGPSData(channel, locationViewModel); }; 
       // Hook up the Elapsed event for the timer. 
       aTimer.AutoReset = true; 
       aTimer.Enabled = true; 
private void PublishGPSData(IModel channel, LocationViewModel locationViewModel) 
{ 
}; 
関連する問題