4

私の C# プログラムには、「ログイン」機能があります。ユーザーがボタンを押すと、プログラムは特定のログイン/パス情報を使用して、POST URL を使用して特定の Web サイトにログインし、Cookie を保存します。ログイン後のWebページは、プログラムでさらに処理されます。次に、結果がユーザーに表示されます。

問題は、ユーザーがボタンをクリックした瞬間に、プログラム全体がハングアップし、上記の操作が完了するまで待機していることです。それは約 3 ~ 5 秒の非アクティブ状態です。

その間、ユーザー入力をブロックし、「作業中...」などのメッセージを表示したいと思います。それ以外の場合、プログラムが実際に何かに取り組んでいるかどうかを判断する方法はありません。これが私が意味することです:

ここに画像の説明を入力

望ましい目標を達成するためにどのようなテクニックを使用する必要がありますか?

4

3 に答える 3

2

UI スレッドでログイン コードを実行しているため、UI がブロックされています。これを回避するには、「BackgroundWorker」を使用するか、4 または 4.5 .NET を使用している場合は、「Tasks」を使用してログイン情報を別のスレッドに移動し、UI のブロックを回避します。

Windows フォームと .NET 4+ の場合、次のように動作する可能性があります。

  private void button1_Click(object sender, EventArgs e)
    {
        progressBar1.Visible = true;
        Task.Factory.StartNew(Login)
            .ContinueWith(t => 
                { 
                    progressBar1.Visible = false; 
                }, TaskScheduler.FromCurrentSynchronizationContext());
    }

    private static void Login()
    {
        // should replace this with actual login stuff
        Thread.Sleep(TimeSpan.FromSeconds(3));
    }

それが何をするかというと、ログイン処理を別のスレッドに移すので、UI スレッドはブロックされません。ログインを開始する前に、スタイルが marque に設定されている進行状況バーを再表示し、ログインが終了すると、進行状況バーを再び非表示にします。
UIがブロックされていない限り、ユーザーはログイン中に必要なものを入力/押すことができるため、解決策は、ログイン前にすべてのコントロールを無効にするか、別のモーダルフォームで進行状況バーを表示して、ユーザーがアプリケーションを次のように表示しないようにすることです。ハングし、プログレス バー フォームが閉じられるまで入力を行うことができません。

更新:別の進行状況フォームで例を追加:

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

    private void button1_Click(object sender, EventArgs e)
    {
        MarqueeForm.DoWithProgress("Doing login", Login);
    }

    private static void Login()
    {
        Thread.Sleep(TimeSpan.FromSeconds(3));
    }
}

public class MarqueeForm : Form
{
    private Label label;

    public MarqueeForm()
    {
        var progressBar = new ProgressBar
                          {
                              Style = ProgressBarStyle.Marquee, 
                              Top = 20, 
                              Size = new Size(300, 15)
                          };

        Controls.Add(progressBar);

        label = new Label();
        Controls.Add(label);
    }

    public static void DoWithProgress(string title, Action action)
    {
        var form = new MarqueeForm
                   {
                       Size = new Size(310, 50),
                       StartPosition = FormStartPosition.CenterParent,
                       FormBorderStyle = FormBorderStyle.FixedDialog,
                       ControlBox = false,
                       label = { Text = title }
                   };

        form.Load += (sender, args) =>
            Task.Factory.StartNew(action)
                .ContinueWith(t => ((Form)sender).Close(),
                    TaskScheduler.FromCurrentSynchronizationContext());

        form.Show();
    }
}
于 2013-05-29T11:27:06.660 に答える
0

button1.Enable = false;ボタンを押すと、 「お待ちください..」などのメッセージを表示しながらボタンを無効にすることができます。処理終了時にボタンを有効にして結果を表示します。

于 2013-05-29T11:19:05.050 に答える