1

ボタンをクリックした後、テキストボックスを継続的に更新する必要がありますが、ボタンは残りのタスクをそのまま実行する必要があります。

簡単なのは、クリックイベントが実行されると、テキストボックスはクリックイベントの完了を待たずに、テキストの継続的な更新を開始することです。

サンプルコード

using System.threading;

namespace name
{
    public class sA
    {
        public void th()
        {
           textbox.invoke(new MethodInvoke(()=> textbox.AppendText("hello\n")));
        }

        private void Button1Click(object sender, EventArgs e)
        {
           thread cThread=new thread(th);
           cThread.start();

           while(true)
           {
               // do any thing
           }
        }
    }
}

重要:: イベント「Cthread.start();」を実行するとき テキスト ボックスはすぐにテキストの更新を開始する必要がありますが、「while ループ」などのクリック イベントの残りの機能は並行して実行する必要があります。

ここに画像の説明を入力

4

3 に答える 3

4

これが Windows フォーム内にある場合Application.DoEvents();は、ループ内の任意の場所に追加します。

private void Button1Click(object sender, EventArgs e)
{
   thread cThread=new thread(th);
   cThread.start();
   while(true)
   {
     // do any thing   
     textbox.Invalidate();
     Application.DoEvents(); // Releases the current thread back to windows form
                          // NOTE Thread sleep different in Application.DoEvents();
                          //Application.DoEvents() is available only in System.Windows.Forms
   }
} 

遅くなりましたが、これがお役に立てば幸いです.. :)

于 2012-09-21T01:57:01.673 に答える
2

ブロックwhile(true)は別のスレッドでも発生する必要があります。

現在、UI スレッドが更新を実行するのをブロックしています。

メソッド th() はバックグラウンド スレッドで実行されていますが、UI スレッドが再び使用可能になるまで Invoke の呼び出しを実行できません。

于 2012-05-18T14:07:18.017 に答える
1

私があなたの質問を正しく理解した場合、ボタンクリック手順が「while」ループ内で実行されている間、TextBoxのテキストを更新し続ける必要があります。テキストボックスがどこから更新されるかを実際に指定していませんが、「while」ループ内のコードからのものであると想定します。

「akatakritos」が述べているように、ボタンクリック内のwhileループが、アプリケーションが停止している理由です。これは、whileループがユーザーインターフェイス(UI)スレッドをブロックしているために発生します。

「while」ループ内でコードを移動して別のスレッド内で実行し、ボタンをクリックしてこの新しいスレッドを開始する必要があります。

これを行う方法は次のとおりですが、最善ではないかもしれませんが、必要なことは実行されます。

新しいクラスを作成します。

public class ClassWithYourCode
{
    public TextBox TextBoxToUpdate { get; set; }
    Action<string> updateTextBoxDelegate;

    public ClassWithYourCode()
    { }

    public void methodToExecute()
    {
        bool IsDone = false;
        while (!IsDone)
        {
            // write your code here. When you need to update the 
            // textbox, call the function:
            // updateTextBox("message you want to send");
            // Below you can find some example code:

            for (int i = 0; i < 10; i++)
            {
                Thread.Sleep(1000);
                updateTextBox(string.Format("Iteration number: {0}", i));
            }

            // Don't forget to set "IsDone" to "true" so you can exit the while loop!
            IsDone = true;
        }

        updateTextBox("End of method execution!");
    }

    private void updateTextBox(string MessageToShow)
    {
        if (TextBoxToUpdate.InvokeRequired)
        {
            updateTextBoxDelegate = msgToShow => updateTextBox(msgToShow);
            TextBoxToUpdate.Invoke(updateTextBoxDelegate, MessageToShow);
        }
        else
        {
            TextBoxToUpdate.Text += string.Format("{0}{1}", MessageToShow, Environment.NewLine);
        }
    }

}

また、button1_Clickメソッド内に、次のコードを追加できます。

private void button1_Click(object sender, EventArgs e)
{
    ClassWithYourCode myCode = new ClassWithYourCode();
    myCode.TextBoxToUpdate = textBox1;

    Thread thread = new Thread(myCode.methodToExecute);
    thread.Start();
}

これで、「while」ループが新しいスレッド内で実行されます。テキストボックスを更新する必要がある場合は、UIスレッド以外のスレッドからWindowsフォームコントロールを更新できないため、UIスレッドから更新します。

于 2012-05-18T15:14:04.950 に答える