开发者

Form Visiblity Problem

开发者 https://www.devze.com 2023-03-26 02:36 出处:网络
Form1.button_Click(...) { // Show a dialog form, which runs a method <CheckBalance()> on it\'s OnLoad Event.
Form1.button_Click(...) {
    // Show a dialog form, which runs a method <CheckBalance()> on it's OnLoad Event.
    var modemDialog = new ModemDialog("COM25");
    modemDialog.ShowDialog();
    // the user can't see this dialog form until the method <CheckBalance()> terminates.
}

Is it possible to show first开发者_如何学编程 the dialog then run the specified method? THanks.


That is correct and expected. Winforms UI is inherently single-threaded. Having a function call like "CheckBalance" in the form load event will prevent the form from showing until the form load event completes. Depending on the duration of the task, you have a number of options available to you:

  1. If it's a fast task, compute it ahead of time before showing the form
  2. If it's something the user may want to initiate, move it to a button on the new form, so it's only calculated on the request of the user
  3. If it's a long running task that takes some time, you'll need to move it off in to another thread. Using a BackgroundWorker is recommended.


OnLoad occurs before the form is shown to allow you to initialise the form and variables and what not, which means it is synchronous. The form will not show until you return from that function.

If you want to asynchronously run the CheckBalance() method, then you can use a few techniques, such as utilising the Threading, ThreadPool or Tasks API to shift that work to a background thread, and returning immediately so that the form is shown.

Here is an example of using a Task to perform the same action, but asynchronously so that the form immediately shows:

Action<object> action = () => { CheckBalance(); };
new Task(action).Start();

Please note that if you access the UI thread, you'll need to beware of thread-safety and invocation.


The simple way to make sure your form is visible before CheckBalance is run is to use this code in the form load handler:

this.BeginInvoke((Action)(() => this.CheckBalance()));

This will push the execution of the CheckBalance method onto the UI thread message pump so will execute after all preceding UI code is complete.

Others are correct though that the UI will still be blocked as CheckBalance executes. You probably want to run it on a background thread to prevent this.

0

精彩评论

暂无评论...
验证码 换一张
取 消