2009-07-12 34 views

答えて

17

Application.DoEventsは、通常、UIスレッドで長時間実行される操作を実行しているときにイベントが定期的に処理されるようにするために使用されます。

もっと良い解決策はそれをしないことです。別のスレッドで長時間実行する操作を実行し、UIを更新する必要がある場合は、UIスレッド(Control.BeginInvoke/InvokeまたはBackgroundWorker)にマーシャリングします。

Application.DoEventsには再入可能性があり、非常に分かりにくいバグにつながる可能性があります。

+0

Jon、 あなたはイベントが定期的に処理されることを確認すると言っています...どのイベントですか?順次プログラミングでは、フォーム上にボタンがあるとします。たとえば、ユーザーがクリックすると、フォームの不透明度が変わります... 今、ボタンのクリック以外はどのような種類のイベントがありますか? – odiseh

+0

アプリケーションのコードが明示的にそれらのほとんどを処理していない場合でも、再描画、サイズ変更、マウスの動きなど、非常に多くのイベントがあります。 –

+0

@JonSkeet 'DoEvents'の有効な使用方法に関するご意見をお待ちしております。 https://stackoverflow.com/questions/45023826/is-this-a-valid-use-of-doevents-sample-project-included –

1

非常に予期しない動作に終わる可能性があるので、使用することは決して避けてください。 ちょうど生成されたコードはOKです。あなたのようなものは、現在のイベントハンドラを再度実行しています。ユーザーがキーを2回押したなどのためです。 現在のプロセスを表示するためにコントロールをリフレッシュする場合は、呼び出す代わりにそのコントロールの.Updateを明示的に呼び出す必要がありますApplication.DoEvents。

2

Windowsは、クリック、サイズ変更、閉じるなどのさまざまなイベントを保持するキューを保持します。コントロールがイベントに応答している間は、他のすべてのイベントがキューに保持されます。したがって、アプリケーションがボタンクリックを処理するのに時間がかかり過ぎると、残りのアプリケーションがフリーズするように見えます。したがって、イベントに応答して処理が多少行われている間に、アプリケーションが応答しなくなる可能性があります。理想的には、UIがフリーズしないように非同期で処理するのが理想的ですが、Application.DoEvents()を定期的に呼び出すだけで、保留中のイベントをアプリケーションに送ることができます。

優れたWindowsアプリケーションの場合、大/大重量の操作を実行しているときにアプリケーションのいずれかのフォームがフリーズしても、エンドユーザーは好きではありません。ユーザーは常にUIをフリーズするのではなく、スムーズに応答してアプリケーションを実行したいと考えています。しかし、私はグーグルで私はApplication.DoEvents()は、アプリケーションでより頻繁に使用する良い習慣ではないことが判明したので、このイベントの代わりに、BackGround Worker Threadを使用してウィンドウをフリーズせずに長時間実行するタスクを実行することをお勧めします。

実際に見た方が良いアイデアを得ることができます。次のコードをコピーして、Application.DoEvents()を置くかどうかでアプリケーションをチェックしてください。

Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click 
     For i As Integer = 0 To 1000 
      System.Threading.Thread.Sleep(100) 
      ListBox1.Items.Add(i.ToString()) 
      Application.DoEvents() 
     Next 
    End Sub 
関連する問題