1

私はこれを理解しようとして最悪の時間を過ごしてきました。糸脱毛に関してはかなり混乱しています。

私がやろうとしているのは、関数で1休止の遅延があり、さらに1秒間休止が来て、最終的に関数が終了するまで関数を継続することです。

public partial class SplashScreen : Form
{
    public SplashScreen()
    {
        InitializeComponent(); // initalize splash screen
        DatabaseStatus(); // set database connection
        getUserInfo(); // get user information
        showInfo(); // show app information on splash screen
        System.Threading.Thread wa = new System.Threading.Thread(new System.Threading.ThreadStart(checkUser));
        wa.IsBackground = true;
        wa.Start();
    }

    void checkUser()
    { 
        if (RegisteredUser)
        {
            richTextBox1.Text += "Loading user settings...";  // SHOW THIS TEXT AND WAIT 1 SECOND UNTIL NEXT
            System.Threading.Thread.Sleep(1000); 

            if (DATABASE_CONNECTION)
            {
                richTextBox1.Text += "Loging on...";
                // WAIT AGAIN 1 SEC AND CONTINUE///
                LoginCheck login = new LoginCheck(USER_NAME, PASSWORD);
                if (login.LOGIN_SUCESS)
                {
                    richTextBox1.Text += "Sucess!";
                   // SHOW THIS TEXT AND WAIT 1 SEC UNTIL SPLASH SCREEN FADE OUT//
                    //MessageBox.Show(login.HASH);
                    opac.Interval = 12;
                    opac.Start();
                    opac.Tick += new EventHandler(dec);
                }
                else
                {
                    MessageBox.Show(login.HASH);
                }
            }
        }
        else
        {
            richTextBox1.Text += "Not user profile found...";
            // ask user to register
        }
    }
}

コメントを配置した場所は、スレッドを一時停止して続行する場所です...

誰か入力がありますか?

ありがとう

4

4 に答える 4

2

まず、WinForms(およびWPF / Silverlight ...でしょ?)を操作するときは、フォーム/コントロールを作成した元のスレッド以外の他のスレッドからUI要素を操作できないことを知っておく必要があります。

非同期作業を行う必要がある場合は、UI作業を使用するInvokeか、フォームまたはコントロールのスレッドに戻す必要があります。また、独自のスレッドを作成するのではなく、BeginInvokeデリゲートを使用することを検討してください(便利です)。MethodInvoker

また、イベント中またはイベント後に非同期作業を開始する必要がありますLoad。そうしないと、フォームが表示される前にロジックの実行が開始されます(以下の例を参照)。

私はあなたの例を取り上げて、それを私自身の単純化されたサンプルに入れました。

public partial class Form1 : Form
{
    public Form1()
    {
        InitializeComponent();

        RegisteredUser = true;
        DATABASE_CONNECTION = true;


    }

    private void UpdateStatus(string message)
    {
        BeginInvoke(new MethodInvoker(() => richTextBox1.Text += message));
    }

    private void CheckUser()
    {
        if (RegisteredUser)
        {
            UpdateStatus("Loading user settings..."); // SHOW THIS TEXT AND WAIT 1 SECOND UNTIL NEXT
            System.Threading.Thread.Sleep(1000);

            if (DATABASE_CONNECTION)
            {
                UpdateStatus("Logging on...");
                //// WAIT AGAIN 1 SEC AND CONTINUE///
                //LoginCheck login = new LoginCheck(USER_NAME, PASSWORD);
                if (true)//login.LOGIN_SUCESS)
                {
                    UpdateStatus("Success!");
                    // SHOW THIS TEXT AND WAIT 1 SEC UNTIL SPLASH SCREEN FADE OUT//
                    //MessageBox.Show(login.HASH);
                    //opac.Interval = 12;
                    //opac.Start();
                    //opac.Tick += new EventHandler(dec);
                }
                else
                {
                    //MessageBox.Show(login.HASH);
                }
            }
        }
        else
        {
            UpdateStatus("No user profile found.");
            // ask user to register
        }
    }

    protected bool DATABASE_CONNECTION { get; set; }

    protected bool RegisteredUser { get; set; }

    private void Form1_Load(object sender, EventArgs e)
    {
        var invoker = new MethodInvoker(CheckUser);
        invoker.BeginInvoke(null, null);
    }
}

ご覧のとおり、私UpdateStatusはUIで作業を行うなどの方法を使用して、UIスレッドで確実に作業を行っています。フォームのフェードをトリガーするなど、UIで他のことを行うために、同様の方法をいくつでも使用できます。

UIスレッドの外にメッセージボックスを表示することすらすべきではありません。同様の方法で安全に呼び出されるようにします(また、デバッグの場合は、Debug.WriteLineメッセージボックス全体をポップアップするのではなく、デバッガーにメッセージを書き込むだけです)。

于 2012-06-08T05:44:48.317 に答える
1

別のバックグラウンドワーカースレッドですべてを実行し、UIでステータスを更新することをお勧めします。これにより、UIが高速になり、アプリケーションの信頼性が高まります。

http://msdn.microsoft.com/en-us/library/cc221403(v=vs.95).aspx

于 2012-06-08T05:40:54.070 に答える
0
public partial class SplashScreen : Form
{      
    bool DATABASE_CONNECTION;
    bool RegisteredUser; // if user has been registered
    string USER_NAME;
    string PASSWORD;
    double LIN_x = 0.01;

    DialogResult result;
    custom con = new custom();
    Timer opac = new Timer();

    public SplashScreen()
    {
        InitializeComponent(); // initalize splash screen
        DatabaseStatus(); // set database connection
        getUserInfo(); // get user information
        showInfo(); // show app information on splash screen
    }

    private void UpdateStatus(string message)
    {
        BeginInvoke(new MethodInvoker(() => richTextBox1.Text += message + Environment.NewLine));
    }

    void checkUser()
    {
        UpdateStatus("Loading user settings..."); 
        if (RegisteredUser)
        {
            UpdateStatus("User " + USER_NAME + " found." );
            if (DATABASE_CONNECTION)
            {
                UpdateStatus("Logging on..."); 
                LoginCheck login = new LoginCheck(USER_NAME, PASSWORD);
                if (login.LOGIN_SUCESS)
                {
                    UpdateStatus("Success! Loading " + con.AppTitle() + "...please wait");

                    //UpdateStatus(login.HASH); return hash string from web site
                    fadeSplash(); // begin fade out of form
                }
                else
                {
                    UpdateStatus("There was an error logging in."); 

                }
            }
            else
            {
                UpdateStatus("No database connection found."); 

            }
        }
        else
        {
            UpdateStatus("No user found"); 

            Reg(); // Registration form
        }
    }

    private void fadeSplash()
    {
        opac.Interval = 12;
        opac.Tick += new EventHandler(dec);
        opac.Start();
    }

    private void dec(object sender, EventArgs e)
    {
        this.Opacity -= LIN_x;
        if (this.Opacity < 0.04)
        {
            opac.Stop();
            this.Hide();
            main open = new main(); // start application
            open.Show();
        }
    }
}

これは、MethodInvoke中にfadeメソッドが起動しないコードです。

于 2012-06-08T19:01:55.080 に答える
0

Invoke()を使用する必要がありますこれを参照してください

于 2012-06-08T05:40:41.840 に答える