2

これが私が持っているものです。アプリケーションが起動すると、スレッドが作成され、startListening()関数が実行されます。startListeningしかし、それがしているように見えるのは、同じスレッドの下で呼び出された他の関数を実行することです。startListeningそのスレッド内から呼び出された関数ではなく、そのスレッドですぐに実行されるものだけを実行する方法はありますか?

そのスレッド内にないコントロールやものを参照するときに、それがずっと簡単になるので、毎回呼び出す必要はありません。

編集:多分これは尋ねるのが正しいことではありません。テキストボックスを設定する必要があることはわかっていInvokeますが、タイマーを有効にする必要があります。有効にしようとしても例外はスローされませんが、「カチカチ音をたてる」だけではありません。これが私のコードです:

    private void beginListenerThread()
    {
        Thread thread1 = new Thread(startListening);
        thread1.Start();
    }

    private void startListening()
    {
        timer1.enabled = true;
    }

しかし、それはカチカチしません。

ありがとう!

4

2 に答える 2

5

いいえ、自動的にはできません。別のスレッドで呼び出す必要があるメソッドを変更できる場合は、元のスレッドで実行されるように、他のメソッドへの呼び出しを変更します。Windows フォームを使用している場合は、たとえば、this.Invokeまたはを使用します。this.BeginInvoke

于 2012-07-21T17:18:13.160 に答える
1

はい、これは、スレッド上でスレッドセーフでないクラスを使用するときに遭遇する種類の問題です。Winforms Timer クラスは、小さな隠しヘルパー ウィンドウ (Windows SetTimer() API 関数によって生成された WM_TIMER メッセージを受け取り、Tick イベント呼び出しに変換するウィンドウ) から Tick イベントを生成します。タイマーを有効にすると、そのウィンドウが作成されます。

ここでうまくいかないのは、このウィンドウが間違ったスレッドで作成されることです。WM_TIMER 通知をディスパッチするにはメッセージ ポンプが必要ですが、そのスレッドにはメッセージ ポンプがありません。Application.Run() を呼び出すことで取得できますが、そこに行きたくありません。

MSDN ライブラリの記事の備考セクションに記載されているアドバイスに従ってください。

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

または、System.Threading.Timer クラス、少し不機嫌なタイマー クラスです。

于 2012-07-21T17:59:45.993 に答える