マルチスレッド アプリケーションでいくつか使用System.Threading.Timer(s)
していますが (実際には 3 つのタイマーを使用しています)、非常にうまく機能しているにもかかわらず、やり方が間違っていて、不要なリソースを消費しているように感じます。実際には、私がやっていることはこれです:
アプリケーションのメイン ウィンドウ (WPF ウィンドウですが、それほど重要ではないと思います) で、3 つのスレッドを開きます。
これら 3 つのスレッドのそれぞれで、3 つのタイマーの 1 つを初期化して開始します。
これを行うために 3 つの異なるスレッドを使用している理由は、どこかで読んだことを覚えているためです (場所が見つかりません) System.Threading.Timer
。タイマー開始時)。
さて、次の単純なアプリケーションをテストしましたが、Timer とそれを開始するスレッドとの間に競合はないようです。
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
System.Threading.Timer _t1, _t2, _t3;
private void Form1_Load(object sender, EventArgs e)
{
_t1 = new System.Threading.Timer(new TimerCallback(_t1Run),
null, TimeSpan.Zero, TimeSpan.FromMilliseconds(15));
_t2 = new System.Threading.Timer(new TimerCallback(_t2Run),
null, TimeSpan.Zero, TimeSpan.FromMilliseconds(35));
_t3 = new System.Threading.Timer(new TimerCallback(_t3Run),
null, TimeSpan.Zero, TimeSpan.FromMilliseconds(150));
for (int i = 1; i <= 5000; i++)
{
Console.WriteLine("Writting on main form " + i);
}
}
void _t1Run(object State)
{
_t1.Change(Timeout.InfiniteTimeSpan, Timeout.InfiniteTimeSpan);
Console.WriteLine("running 1");
_t1.Change(TimeSpan.FromMilliseconds(15), TimeSpan.FromMilliseconds(15));
}
void _t2Run(object State)
{
_t2.Change(Timeout.InfiniteTimeSpan, Timeout.InfiniteTimeSpan);
Console.WriteLine("running 2");
_t2.Change(TimeSpan.FromMilliseconds(35), TimeSpan.FromMilliseconds(35));
}
void _t3Run(object State)
{
_t3.Change(Timeout.InfiniteTimeSpan, Timeout.InfiniteTimeSpan);
Console.WriteLine("running 3");
_t3.Change(TimeSpan.FromMilliseconds(150), TimeSpan.FromMilliseconds(150));
}
}
では、メイン ウィンドウで 3 つのタイマーをすべて開始できますか (または別のスレッドが必要ですか)。これが問題を引き起こさないことを誰かが確認できますか (私がテストしたアプリケーションでは問題がないように見えるため)。
編集: 3 つのタイマーには異なる目的があり、そのうちの 2 つは実際にはいくつかの UI 相互作用を持っています (1 つはメイン ウィンドウと相互作用し、もう 1 つはセカンダリ ウィンドウと相互作用します - 3 つ目はバックグラウンド操作のみを行います)。使用System.Windows.Forms.Timer
は、タイマーが多くの操作を行うことであり、メインスレッドでこれらすべての操作を行う場合、すべての GUI 対話を実際にブロックするよりも (私はこれらのタイマースレッドを 100 ~ 200 ミリ秒の間隔で呼び出すので、想像 ...) 。これは、タイマーによって呼び出されたスレッドから GUI の対話を行う方法の例です。
MainWindow.ThisInstance.TitleLabel.Dispatcher.BeginInvoke((Action)(() => UpdateMainWindow_TimeLabel(TimeLabelValue)));