1

私は自分のプログラムで問題に直面しています。プログラムはログインチェッカーであり、ユーザーとパスワードのリストを読み取り、1つずつログインをテストします。私が直面している問題は、長いリストを入れるとプログラムに時間がかかり、キャンセルボタンまたは一時停止が必要になることです. プログラムがそのループ (ログイン テスト) で実行されている間、ウィンドウ フォームがフリーズし、ボタンを押したりドラッグしたりすることさえできません。ここにループがあります:

private void button1_Click(object sender, EventArgs e)
{
    string spl = textBox5.Text;
    int lin = textBox4.Lines.Count();

    for (int i = 0; i < lin; i++)
    {
        string dick = textBox4.Lines[i];
        Convert.ToString(dick);
        string[] wordArray = dick.Split(':');

        textBox1.Text = (Convert.ToString(wordArray[0]));
        textBox2.Text = (Convert.ToString(wordArray[1]));
        login();
    }
}
4

3 に答える 3

2

まず、なぜこのような問題に直面しているのかを説明したいと思います。
メイン スレッド (UI スレッド) で「重い」操作を実行していますが、このスレッドがタスク (ユーザーとパスワードのチェック) でビジー状態である間、UI メッセージに応答しません。つまり、メッセージ キューが空かどうかはチェックしないので、操作が終了するまでクリックしても何もしません。
第二に、それを解決するいくつかの方法を見つけたいと思います。
解決策 1バックグラウンド スレッドを使用して作業を行う

    using System.Threading;
    private void button1_Click(object sender, EventArgs e)
    {
        Thread thread = new Thread(() => {
            this.Invoke(new Action(() => {
                string spl = textBox5.Text;
                int lin = textBox4.Lines.Count();
                for (int i = 0; i < lin; i++) {
                    string dick = textBox4.Lines[i];
                    Convert.ToString(dick);
                    string[] wordArray = dick.Split(':');

                    textBox1.Text = (Convert.ToString(wordArray[0]));
                    textBox2.Text = (Convert.ToString(wordArray[1]));
                    login();
                }
            }));
        });
        thread.Start();
    }

このようにして、操作を行っているときに応答する UI を作成します。

解決策 2 BackgroundWorker を使用する
解決策 1 と似ていますが、ユーザーが作成したバックグラウンド スレッドをSystem.ComponentModel.BackgroundWorkerに置き換えるだけです。BackgroundWorker を使用する方法については、 https://msdn.microsoft.com/zh-cnを参照してください。詳細については、 /library/system.componentmodel.backgroundworker.aspxを参照してください。

解決策 3 ThreadPool
を使用する System.Threading.ThreadPool を使用して、機能するバックグラウンド スレッドを作成します。これにより、自分でスレッドを管理する必要がなくなります。詳細については、https://msdn.microsoft.com/zh-cn/library/system.threading.threadpool (v=VS.80).aspx を参照してください。

解決策 4タスク
を使用する System.Threading.Task を使用して操作を実行します。msdn を参照してください:
https:// msdn.microsoft.com/zh-cn/library/system.threading.tasks.task.aspx
注意: System.Threading.Taskは .NET Framework 4.0 から利用できます。

ところで、上記のソリューションを使用する場合は、Form.Invoke()を使用してフォーム上のコントロールにアクセスするか、Control.CheckForIllegalCrossThreadCallsを false に設定することを忘れないでください。

于 2015-08-12T14:31:46.847 に答える
1

これは、UI スレッドで実行されているために発生します。.net >=4.5 を使用している場合は、Task.Run()を使用してみてください

さらに、キャンセル トークンを使用してログイン プロセスを停止できます。

于 2015-08-12T13:29:40.407 に答える
0

まあ、それは単にスレッドの問題です。ログイン メソッドは、UI が使用するスレッドであるデフォルト スレッドで実行されています。したがって、コードがこのスレッドを使用してログインを試みている間、スレッドがビジーであるため、UI でのアクションの実行はブロックされます。

必要なことは、UI スレッドをブロックしないように、ログインを別のスレッドで実行できるようにすることです。これは、 TasksBackgroundworkerなど、さまざまな方法を使用して実行できます。これらはどちらもキャンセルもサポートしています。つまり、現在の操作を停止するようにトリガーすることができます。

于 2015-08-12T13:36:46.007 に答える