特定のコレクションを取得し、アイテムをコピーし(ItemクラスにはCopy()メソッドが適切に定義されています)、アイテムにデータを入力し、入力されたコレクションをクラスのコレクションプロパティに返す、かなりプロセス集約的なメソッドがあります。
//populate Collection containing 40 items
MyClass.CollectionOfItems = GetPopulatedCollection(MyClass.CollectionOfItems );
このメソッドは、要求に応じて、およびSystem.Timers.Timerオブジェクトの「Elapsed」イベントを介して2つの方法で呼び出されます。
現在、コレクション内の40のアイテムは、ほとんど時間がかかりません。button_clickなどによって「アドホック」に入力されるか、Timerオブジェクトによって入力されるか。
コレクション(1000個のアイテムを持つ別のMyClassオブジェクト)のサイズを大きくすると、予想どおりにプロセスに時間がかかりますが、合計で約6秒かかります。それは問題ありません。問題はありません。初期化時に呼び出されるか(form_load)、アドホックに呼び出される(button_click)と、約6秒続きます。
//populate Collection containing 1000 items
MyClass.CollectionOfItems = GetPopulatedCollection(MyClass.CollectionOfItems );
ただし、同じメソッド(コードの正確な行と同様)がSystem.Timers.Timerオブジェクトによって呼び出されています。そして、その経過には約60秒かかります(他の実行では、56秒、1分2秒、1分10秒...アイデアがわかります)。同じプロセスで10倍の長さです!
System.Timers.Timerオブジェクトがスレッドプールで実行されていることは知っています。これが理由でしょうか?スレッドプールの優先度が低くなっていますか、それともキューイング全体に時間がかかっていますか?
要するに、これへのより良いアプローチは何でしょうか?System.Windows.Forms.Timerを使用して同じUIスレッドで実行しますか?
ありがとう!
わかりました、いくつかの追加情報:
タイマー操作は、UIによって呼び出されているDLL内で発生しています。メインの「handler」クラス自体には、すべて同じイベントハンドラーにサブスクライブしているタイマーオブジェクトのコレクションがあります。ハンドラークラスの初期化は、次のように機能します。
UpdateIntervalTimer tmr = new UpdateIntervalTimer(indexPosition);
tmr.Interval = MyClass.UpdateInterval * 60000; //Time in minutes
tmr.Elapsed += new System.Timers.ElapsedEventHandler(tmr_Elapsed);
this.listIntervalTimers.Add(tmr);
私は実際にTimerクラスを継承して、それに'index'プロパティを与えました(eventArgsも同様です)。このようにして、1つのイベントハンドラー(tmr_Elapsed)内で、タイマーの対象となるMyClassオブジェクトを識別し、アクションを実行できます。
ハンドラークラスはすでに独自のスレッドで実行されており、カスタムイベントを発生させて、その操作に関する洞察を提供します。イベントはUI(UIコントロールのクロススレッドアクセスなど)で処理され、イベントが処理された時刻とともに表示されます。これは、「初期化」呼び出しと「アドホック」呼び出しの両方に当てはまります(これらの場合は問題ありません)。
実際の経過イベントは次のようになります。
private void tmr_Elapsed(object sender, System.Timers.ElapsedEventArgs e)
{
UpdateIntervalTimer tmr;
tmr = (UpdateIntervalTimer)sender;
MyClass c = listOfClasses[tmr.IndexPosition];
observerEventArguments = new MyHandlerEventArgs("Timer is updating data for " + MyClass.ID);
MessagePosted(this, observerEventArguments);
try
{
//preparation related code
MyClass.CollectionOfItems = GetPopulatedCollection(MyClass.CollectionOfItems);
observerEventArguments = new ProfileObserverEventArgs(MyClass.ID + ": Data successfully updated");
MessagePosted(this, observerEventArguments);
}
catch (Exception exUpdateData)
{
observerEventArguments = new MyHandlerEventArgs("There was an error updating the data for '" + MyClass.ID + "': " + exUpdateData.Message);
MessagePosted(this, observerEventArguments);
}
}