は、物事の仕組みあなたを説明しようとする二つのリンクに行く:今 (1)(2)
を、私はすぐに私ができるようにそれを説明しようとします。 Windowsフォームアプリケーションの中で起きることのほとんどは、通常は同じスレッドMain()が実行されます。Program.csを開くと、Main()に次のような行が表示されます。
Application.Run(new Form1());
いつでもアプリケーションをデバッグしてコールスタックを調べると、そのRunメソッドにトレースされることがわかります。これは、Windows Formsアプリケーションが実際にはRunメソッドの連続実行であることを意味します。 Runは何をしていますか? Runは、Windowsがメッセージを送信するメッセージキューを使用しています。実行した後、それらのメッセージを正しいコントロールに送ります。それ自体は、押されているキーに対応するテキストを追加したり、再描画したりします。これはすべて単一のスレッドと同時に実行されるエンドレスループです。または単純にウィンドウを移動すると、それらのメッセージのロードがアプリケーションに渡され、アプリケーションがそのスレッドを処理してそれに応じて反応します。コントロールはキューを介して自分自身にメッセージを送信することもでき、Control.BeginInvoke経由でポンプにメッセージを配置することもできます。これらのコントロールが行うことの1つは、何が起こるかに応じてイベントを発生させることです。したがって、ボタンをクリックすると、そのクリックを処理するために作成したコードは、最終的かつ間接的にApplication.Runメソッドによって実行されます。
コードでは、進行状況バーの可視状態を可視に変更して値を更新しても、同じ方法で可視性をfalseに変更しています。つまり、メソッドを終了した後でも、Application.Run()はメッセージキューの反復処理を継続し、プログレスバーにその表示を更新するように効果的に指示します。そのようなことが起こると、メソッドを終了する前に最後に行った進捗バーの可視性を既にfalseにしています。 DoEvents()は、キュー内のメッセージを読み込んで処理するため、問題をすばやく解決する方法です。私はそれがリエントラントの問題を引き起こす可能性があるので、実際にそれを使うのが快適ではないと感じています。
スレッドを使用することは良い解決策ですが、この種の状況ではカスタムスレッドの代わりにThreadPoolスレッドを使用することをお勧めします。長寿命スレッドの数が限られている場合にのみカスタムスレッドを使用する傾向があります。私は彼らのライフサイクルをコントロールする必要があります。スレッドを使用する最も簡単で実用的な方法は、実際に何が起こっているのかを本当に理解したい場合は、デリゲートでWindows Formsマルチスレッドを実行する方法を理解することが苦労することをお勧めしますが、BackgroundWorkerコンポーネントを使用することです。
長時間実行しているプロセスを別のスレッドに移動して、常に使用可能なUIを維持することをお勧めしますか? –
はい、それはBackgroundWorkerが簡単にするものです。 –
ヘルプをよろしくお願いします。私はスレッドを避けることを望んでいました。なぜなら、それらは手作業ではかなり難しく、これは単純なUIですが、これは完璧と思われます。ありがとう。 –