5

こんにちは、Timer.Timer クラスの Elapsed イベントをメイン スレッドで発生させようとしています。私は VS 2008、.net 3.5 に制限されています... この投稿では: C# タイマーは別のスレッドで経過しますか? SynchronizingObject を使用すると、オブジェクトを所有するスレッド上でハンドラーが実行されることが示されています。

だから私はこれを試しました:

class MyTimer
{
  private readonly Timer timer;

  public MyTimer(ISynchronizeInvoke synchronizingObject)
  {
    Console.Out.WriteLine(Thread.CurrentThread.ManagedThreadId);
    timer = new Timer(1000);
    timer.SynchronizingObject = synchronizingObject;
    timer.Elapsed +=
      delegate
        {
          timer.Stop();
          Thread.Sleep(2000);
          Console.Out.WriteLine(Thread.CurrentThread.ManagedThreadId);
          timer.Start();

        };
    timer.Start();
  }
}

class Program
{
  static void Main(string[] args)
  {
    ISynchronizeInvoke syncObject = new Control();
    var mytimer = new MyTimer(syncObject);

    Console.ReadKey();
  }
}

しかし、出力は次のとおりです。1,4,4,4,4...

何故ですか?Elapsed ハンドラーをメインスレッドで実行するにはどうすればよいですか。

イベントに SynchronizingObject を使用してみまし たが、どちらも役に立ちませんでした。

  public static ElapsedEventHandler Wrap(ElapsedEventHandler original, ISynchronizeInvoke synchronizingObject) 
  {
    return (sender, args) =>
    {
      if (synchronizingObject.InvokeRequired)
      {
        synchronizingObject.Invoke(original, new object[] { sender, args });
      }
      else
      {
        original(sender, args);
      }
    };
  }

と:

timer.Elapsed += Wrap(
      delegate
        {
          timer.Stop();
          Thread.Sleep(200);
          Console.Out.WriteLine(Thread.CurrentThread.ManagedThreadId);
          timer.Start();
        }, 
        synchronizingObject);

しかし、まだ成功していません... InvokeRequiredがfalseになるたびに...

デバッグを呼び出しに強制すると、無効な操作が発生します。「ウィンドウ ハンドルが作成されるまで、コントロールで Invoke または BeginInvoke を呼び出すことはできません。」

最後の手段は、http: //www.codeproject.com/Articles/12082/A-DelegateQueue-Class ?msg=3655119#xx3655119xxを調べることです が、それは本当に必要ですか? または、より簡単な解決策がありますか?

4

2 に答える 2

2

DispatcherTimer と Dispatcher.Run() を使用して新しいスレッドでメッセージ ポンプを開始する解決策を見つけました。ディスパッチャーを停止してサービスをスムーズに終了するには、使用しました

if (_currentDispatcher != null) _currentDispatcher.InvokeShutdown();
_thread.Join();
于 2012-10-18T07:43:36.840 に答える