2

バックグラウンダー スレッド内で System.Windows.Forms.Timer を使用する方法を探しています。バックグラウンドスレッド内で開始および停止するのに苦労しています。これは私がやっていることです:

private System.Windows.Forms.Timer chkTimer = new System.Windows.Forms.Timer();

次に、backgroundworker_dowork メソッドで私はこれを持っています:

     chkTimer.Interval = 2000;
     chkTimer.Tick += new EventHandler(chkTimer_Tick);
     chkTimer.Start();

Tick メソッドにはタイマー関連のコードがありますが、何らかの理由で実行されません。上記をUIスレッドで宣言すると動作します。バックグラウンドスレッド内でタイマーを開始するのを手伝ってもらえますか? 私は System.Timers を使いたくないので、それを提案しないでください

ありがとう

4

7 に答える 7

3
using System.Timers;
using System.Threading.Tasks;
.
.
.
var timer = new Timer(250);
.
.
.
private void Initialize()
{
    timer.Elapsed += (o, s) => Task.Factory.StartNew(() => OnTimerElapsed(o, s));
    timer.Start();
}
.
.
.
private void OnTimerElapsed(object o, ElapsedEventArgs s)
{
    //Do stuff
}

必要に応じて、OnTimerElapsed パラメータ "o" および "s" を取り除くこともできます。

于 2013-01-04T22:44:50.887 に答える
2

フォームのタイマーは、メッセージをフォームのハンドル (メッセージ) に投稿することによって機能します。メッセージは、フォームのメッセージ ループによって処理される必要があります。バックグラウンド スレッド (通常) にはメッセージ ループがないため、WM_Timer メッセージはポストされますが、どこにも行きません (コールバックは呼び出されません)。

System.Timers を使用することの何が問題になっていますか?

于 2011-06-22T20:18:18.490 に答える
2

私はタイマーをまったく使用しません。その余分な荷物です。私が読んだところによると、UI とバックグラウンド スレッドの 2 つのスレッドが必要です。

そのため、タイマーではなくバックグラウンド スレッドで間隔を管理します。

疑似コード:

YourFileChecker checker = new YourFileChecker();
checker.CheckInterval = 60000; //milliseconds, the background thread will manage the interval

System.Threading.Thread t = new System.Threading.Thread(new System.Threading.ThreadStart(checker.Check));
t.Start();

次に、Check メソッドに次のようなことをさせます。

 while(!_Stop)
 {
      //Do your work here

      //Wait the specified interval before checking again...
      Thread.Sleep(_CheckInterval);
 }

バックグラウンド スレッドは、停止するように指示される (信号が送られる) までチェックを続けるようになりました。スレッドが間隔を管理しているため、タイマーはまったく必要ありません。

于 2011-06-22T21:44:56.533 に答える
1

だけを使用する必要がありますBackgroundWorkerBackgroundWorkerプロパティを有効にしますWorkerSupportsCancellation。メソッドにDoWork次を追加します。

while(!yourBGWorker.CancelationPending)
{
   //Do some work
   Thread.Sleep(2000);
}

それはあなたが望むことをします-バックグラウンドスレッドでいくつかの作業を行い、指定された期間待機します。また、呼び出し後に進行状況をキャンセルすることもできますyourBGWorker.CancelAsync();

于 2011-06-22T20:27:59.137 に答える
1

ドキュメントから:

Windows フォーム タイマー コンポーネントはシングル スレッドであり、精度は 55 ミリ秒に制限されています。精度の高いマルチスレッド タイマーが必要な場合は、System.Timers 名前空間の Timer クラスを使用します。

名前空間のほとんどのコンポーネントは、System.Windows.Formsバックグラウンド スレッドで実行するようには設計されていません。

于 2011-06-22T20:18:23.057 に答える
0

私は最近あなたが探しているものかもしれない記事を書きました。これは、c#で、指定された間隔で実行され、バックグラウンドスレッドを使用して指定されたユーザーアクションを実行する汎用ポーリングコンポーネントを示しています。これをメインスレッドで起動して、ワーカースレッドでイベントを実行できます。

使用例:

IPoller poller = new UrlPoller(args[0], TimeSpan.FromSeconds(7));
IPolling pollingComponent = new Polling.Core.Polling(poller);
pollingComponent.SubscribeForPollingUpdates(PollingAction);
pollingComponent.Start();

コードと完全な使用法について:

http://www.avantprime.com/blog/24/an-example-of-repeating-code-using-a-worker-thread-without-using-timers-c

于 2012-09-14T15:53:49.957 に答える
0

System.Windows.Forms.Timer は完全に Win32 メッセージに基づいているため、メッセージ ループが必要です。つまり、UI スレッドでのみ実行できます。代替手段は System.Threading.Timer です。これは別のスレッドで動作しますが、うまくいかないとあなたは言います。私の知る限り、任意のスレッドにディスパッチするタイマーを作成する方法はありません (ただし、ディスパッチは自分で行うことができます)。技術的には、スレッドで 2 番目のメッセージ ループを開始し、そこで Windows フォーム タイマーを実行することは可能ですが、お勧めしません (メッセージを送り出す必要があるなど)。通常、これを行うためのより良い方法があります。

于 2011-06-22T20:18:22.023 に答える