0

さて、私はこのtimerコントロールを持っています。プログラムを開始すると問題なく動作しますが、フォームを最大化または最小化すると、タイマー コントロールが機能しなくなります。何も更新されませんか?これがコードです

public MainForm()
        {
            InitializeComponent();
            var tm =
                new System.Threading.Timer(state => statusDateTimeLabel.Text = DateTime.Now.ToLocalTime().ToString(CultureInfo.InvariantCulture), null, TimeSpan.FromMilliseconds(0),
                TimeSpan.FromMilliseconds(1000));                
        }

ラベルが更新されないこともあれば、更新されることもあります。しかし、主な問題は、フォームを最大化し、再度復元すると、時間の更新が停止することです。誰が私が間違っているのか説明してもらえますか?

明確でない場合、ステータス バーにこのラベル コントロールがあり、そのラベルに現在の日時を表示したいと考えています。

このスレッドが別のことで忙しいのかもしれないと思って、これも試してみました

public MainForm()
    {
        InitializeComponent();
        ThreadPool.QueueUserWorkItem(delegate(object state)
                                         {
                                             new System.Threading.Timer(
                                                 stateObj =>
                                                 statusDateTimeLabel.Text =
                                                 DateTime.Now.ToLocalTime().ToString(CultureInfo.InvariantCulture),
                                                 null, TimeSpan.FromMilliseconds(0),
                                                 TimeSpan.FromMilliseconds(1000));
                                         });
    }

しかし、これも上記と同じように機能し、更新される場合と更新されない場合があります。フォームを最大化したり、サイズを変更したりすると、更新が停止するのでしょうか? 誰でも問題が何であるかを理解するのを手伝ってもらえますか?

4

3 に答える 3

3

テキストを更新するためのコールバックが UI スレッドで実行されていません。次のことを試してください。

var context = SynchronizationContext.Current;
var tm = new System.Threading.Timer(state => 
{
  context.Send(delegate() { statusDateTimeLabel.Text = DateTime.Now.ToLocalTime().ToString(CultureInfo.InvariantCulture); });
}, null, TimeSpan.FromMilliseconds(0), TimeSpan.FromMilliseconds(1000));
于 2012-10-16T10:07:24.010 に答える
2

それへの参照を維持していないため、ある時点でガベージコレクションされます。参照Timer:

Timerを使用している限り、それへの参照を保持する必要があります。他のマネージド オブジェクトと同様に、 Timerへの参照がない場合、 Timerはガベージ コレクションの対象になります。タイマーがまだアクティブであるという事実は、収集を妨げるものではありません。

そして、やります:

Timer tm; //Moved to a field

public MainForm()
        {
            InitializeComponent();
            tm =
                new System.Threading.Timer(state => statusDateTimeLabel.Text = DateTime.Now.ToLocalTime().ToString(CultureInfo.InvariantCulture), null, TimeSpan.FromMilliseconds(0),
                TimeSpan.FromMilliseconds(1000));                
        }

(ただし、他の人が指摘しているように、タイマー コールバックで実行している作業が UI とやり取りしている場合は、おそらく間違ったコンポーネントを選択している可能性があります)

于 2012-10-16T10:08:49.473 に答える
0

Windows フォームを使用している場合は、System.Threading.Timer の代わりに System.Windows.Forms.Timer を使用する必要があります: http://msdn.microsoft.com/en-us/library/system.threading.timer.aspx

于 2012-10-18T15:12:23.147 に答える