2011-11-07 5 views
3

私のアプリケーションにはアクセスが制限されています。私は小さなダイアログでユーザー/パスワードボックスを持っています。ログインすると、非常に大きなフォームにたくさんのコントロールと大きなグリッドが読み込まれます。 InitializeComponent()は、をロードするのにほぼ10秒かかり、のデータはありません。ユーザーがログイン中にメインフォーム全体をあらかじめ読み込むテキストボックス

問題は次のとおりです。ユーザーが2つのログインフィールドを入力しているときにFormコンストラクタ()を事前実行する方法は?ユーザーが非常に遅く、認証を完了するために10秒以上が必要な場合は、アプリケーションを表示するのにウインクと同じくらい早くなります。

2つの別々のトップレベルウィンドウがあると思いますが、実装方法はわかりません。 BackgroundWorker、新しいスレッド、...?どんな手掛かり ?

SOLUTION:

イーモンMcEvoyさんの例に続いて、私は私のprerequesitesに関するいくつかの修正を追加しました:私は、ログインダイアログを表示したい、そして成功したログインしている場合、私は大きなフォームを表示。

[STAThread] 
static void Main() 
{ 
    Launcher context = new Launcher(); 
    Application.Run(context); 
} 


public class Launcher : ApplicationContext 
{ 
    private BigForm _bigForm; 
    private Thread _loginThread; 
    private SynchronizeLogin _sharedLogin; 

    public class SynchronizeLogin 
    { 
     private bool _waited = false; 
     public bool IsInitialized 
     { 
      get // loginform should wait before closing until return true 
      { 
       lock (this) 
       { 
        return _waited; 
       } 
      } 
      set // must be set when bigform is initialized 
      { 
       lock (this) 
       { 
        _waited = value; 
       } 
      } 
     } 

     private DialogResult _logged = DialogResult.None; 
     public DialogResult loginResult 
     { 
      get // wait until loginform close 
      { 
       lock (this) 
       { 
        if (_logged != DialogResult.None) 
         return _logged; 
        else 
        { 
         Monitor.Wait(this); 
         return _logged; 
        } 
       } 
      } 
      set // set from loginform when closing 
      { 
       lock (this) 
       { 
        _logged = value; 
        Monitor.Pulse(this); 
       } 
      } 
     } 
    } 

    public Launcher() 
    { 
     // sync obj between forms 
     _sharedLogin = new SynchronizeLogin(); 
     _loginThread = new Thread(new ThreadStart(LaunchLogin)); 
     _loginThread.Start(); 

     // first form 
     _bigForm= new BigForm(_sharedLogin); 
     _bigForm.Closed += new EventHandler(OnFormClosed); 

     // notify login thread that the main one is ready 
     // from now, the login form should be near closing 
     _sharedLogin.IsInitialized = true; 

     WaitLogon(); 
    } 

    private void WaitLogon() 
    { 
     if (_sharedLogin.loginResult == DialogResult.OK) 
     { 
      _bigForm.LoginSuccessful(); // read and use auth session 
      _bigForm.Show(); 
     } 
     else 
     { 
      // escape on user login form 
      // (other exit calls are not working in ctor) 
      Environment.Exit(42); 
     } 
    } 

    private void LaunchLogin() 
    { 
     // ask user 
     LoginDialog _loginForm = new LoginDialog (_sharedLogin); 
     _sharedLogin.loginResult = _loginForm.ShowDialog(); 

     // userlogin form closed 
     // end only current thread 
     Application.ExitThread(); 
    } 

    private void OnFormClosed(object sender, EventArgs e) 
    { 
     // big form closed 
     // end ApplicationContext globally 
     base.ExitThread(); 
    } 
} 

答えて

2

あなたのメインウィンドウのコンストラクタ

using System.Threading; 

private AuthSession _authSession; 

public MainWindowConstructor() 
{ 
    Thread loginThread = new Thread(new ThreadStart(Login()); 
    loginThread.Start(); 
    //Continue initializing 
} 

private void Login() 
{ 
    LoginWindow loginWindow = new LoginWindow(); 
    _authSession = loginWindow.GetAuthSession(); 
    loginWindow.Close(); 
} 
+0

ニースから新しいスレッドでログインウィンドウを作成することができます! LoginWindowから作成した認証セッションをMainWindowに転送する方法を知っていますか? – Doomsday

+0

@Doomsday私の編集を参照してください、これが動作するかどうかお知らせください。あるいは、バックグラウンドワーカーを使用して、RunWorkerCompletedメソッドでAuthSessionを返すこともできます。 –

関連する問題