2017-12-18 6 views
0

こんにちは、私はボタンを生成コードは

Iを提出押すとme.Iのために必要とされるコードを取得するには、Windowsフォームアプリケーションでのプログラムは、UIをブロックしていないためにそれを設定したい作られたWindowsフォームで正常に動作していません

..私はInvalidOperationExceptionがが未処理の例外だっ取得that.Butのためにこれらのコードを使用し、ここで私は、これは、ボタンのクリックイベント

ある

void Generate() 
{ 
    textBox2.Text = ""; 

    string[] sss = textBox1.Text.Split('\n'); 

    textBox2.Text = "VERSION BUILD=8820413 RECORDER=FX" + Environment.NewLine + 
    "SET !ERRORIGNORE YES" + Environment.NewLine + 

     "SET !TIMEOUT_TAG 3" + Environment.NewLine + 
     "SET !TIMEOUT_STEP 3" + Environment.NewLine + 
     "SET !TIMEOUT_PAGE 7" + Environment.NewLine + 
     "SET !REPLAYSPEED FAST" + Environment.NewLine; 
    string[] emails = textBox3.Text.Split('\n'); 

    // label2.Text = emails.Length.ToString(); 
    //foreach (string email in emails) 
    for (int i = 0; i < Convert.ToInt32(textBox5.Text); i++) 
    { 
     textBox2.Text += "TAB T=1" + Environment.NewLine + "CLEAR" + Environment.NewLine + 
      "URL GOTO=https://signin.ebay.com/ws/eBayISAPI.dll?SignIn&lgout=" + Environment.NewLine + 
      "WAIT SECONDS=1" + Environment.NewLine + 
      "TAG POS=1 TYPE=INPUT:SUBMIT FORM=ID:SIGNINFORM ATTR=ID:SUBMIT" + Environment.NewLine + 
      "SET !ENCRYPTION NO" + Environment.NewLine + 
      "TAG POS=1 TYPE=INPUT:PASSWORD FORM=ID:SIGNINFORM ATTR=ID:PASS CONTENT=Maths7524" + Environment.NewLine + 
      "TAG POS=1 TYPE=INPUT:TEXT FORM=ID:SIGNINFORM ATTR=ID:USERID CONTENT=" + emails[i] + Environment.NewLine + 
      "TAG POS=1 TYPE=INPUT:SUBMIT FORM=ID:SignInForm ATTR=ID:sgnBt" + Environment.NewLine + "WAIT SECONDS=7" + Environment.NewLine; 
     foreach (string item in sss) 
     { 

      textBox2.Text += "URL GOTO=www.ebay.com/itm/" + item + Environment.NewLine + "WAIT SECONDS=1" + Environment.NewLine + "TAG POS=1 TYPE=SPAN ATTR=ID:watchLabel" + Environment.NewLine + "TAG POS=1 TYPE=A ATTR=TXT:Watch" + Environment.NewLine + "WAIT SECONDS=1" + Environment.NewLine + Environment.NewLine; 
     } 
    } 
} 

を試してみました

private void button1_Click(object sender, EventArgs e) 
{ 
    //Generate(); 

    Thread thead = new Thread(() => 
    { 
     Generate(); 
     label6.Text = "Done."; 
    }); 
    thead.Start(); 

    label6.Text = "Generating Code.. Please wait...."; 
} 
+0

https://stackoverflow.com/questions/661561/how-do-i-update-the-gui-from-another-thread-in-c [私はGUIを更新するにはどうすればよいの – Steve

+3

可能な複製C#の別のスレッドから?](https://stackoverflow.com/questions/661561/how-do-i-update-the-gui-from-another-thread-in-c) – dlatikay

+0

私はその重複ではないと思いますが、いくつかの改良点と同様に、おそらくスレッドをまったく使用する必要はありません。 –

答えて

2

UIスレッドのみがUIを更新できます。時間のかかるI/O操作や長時間実行される計算を別のスレッドで実行することは理にかなっています。ただし、基本的に別のスレッドのテキストボックスのみを更新するメソッドを実行するのは意味がありません。このメソッドはテキストボックス上でInvokeを呼び出し、テキストボックス操作をUIスレッド上で再度実行する必要があります。

clickイベントでこのメソッドを実行するだけです。

あなたはStringBuilderを使用し、一度だけ、テキストボックスに割り当てることによって、方法をスピードアップすることができます。

string[] sss = textBox1.Text.Split('\n'); 
string[] emails = textBox3.Text.Split('\n'); 

var sb = new StringBuilder(); 
sb.AppendLine("VERSION BUILD=8820413 RECORDER=FX"); 
sb.AppendLine("SET !ERRORIGNORE YES"); 
sb.AppendLine("SET !TIMEOUT_TAG 3"); 
sb.AppendLine("SET !TIMEOUT_STEP 3"); 
sb.AppendLine("SET !TIMEOUT_PAGE 7"); 
sb.AppendLine("SET !REPLAYSPEED FAST"); 

for (int i = 0; i < Convert.ToInt32(textBox5.Text); i++) 
{ 
    sb.AppendLine("TAB T=1").AppendLine("CLEAR"); 
    sb.AppendLine("URL GOTO=https://signin.ebay.com/ws/eBayISAPI.dll?SignIn&lgout="); 
    sb.AppendLine("WAIT SECONDS=1"); 
    sb.AppendLine("TAG POS=1 TYPE=INPUT:SUBMIT FORM=ID:SIGNINFORM ATTR=ID:SUBMIT"); 
    sb.AppendLine("SET !ENCRYPTION NO"); 
    sb.AppendLine("TAG POS=1 TYPE=INPUT:PASSWORD FORM=ID:SIGNINFORM ATTR=ID:PASS CONTENT=Maths7524"); 
    sb.Append("TAG POS=1 TYPE=INPUT:TEXT FORM=ID:SIGNINFORM ATTR=ID:USERID CONTENT=").AppendLine(emails[i]); 
    sb.AppendLine("TAG POS=1 TYPE=INPUT:SUBMIT FORM=ID:SignInForm ATTR=ID:sgnBt"); 
    sb.AppendLine("WAIT SECONDS=7"); 
    foreach (string item in sss) 
    { 
     sb.Append("URL GOTO=www.ebay.com/itm/").AppendLine(item); 
     sb.AppendLine("WAIT SECONDS=1").AppendLine("TAG POS=1 TYPE=SPAN ATTR=ID:watchLabel"); 
     sb.AppendLine("TAG POS=1 TYPE=A ATTR=TXT:Watch").AppendLine("WAIT SECONDS=1").AppendLine(); 
    } 
} 
textBox2.Text = sb.ToString(); 

文字列は不変です。新しい文字列オブジェクトが毎回作成され、古い文字列オブジェクトの内容が新しい文字列オブジェクトの内容と新しいテキストにコピーされるので、文字列を繰り返し連結することは効率的ではありません。一方、StringBuilderは、最大容量に達するまで拡張できる内部ストリングバッファーで動作します。次に、ラガーバッファを作成し、古いバターのテキストを新しいバッファにコピーします。この新しいバッファには十分な空き領域があるため、新しいサイズ変更操作を実行する前に多くの新しいテキスト部分を追加できます。

テキストボックスでもイベントが発生するため、同じテキストボックスに繰り返し割り当てることは時間がかかります。最終的なテキストを一度割り当てるだけで、それ以上の処理が高速化されます。

このように、マルチスレッド化することなく十分速くなると思います。そうでなければ、私は文字列を作成し、それを使って待つことができるタスクを作成するメソッドを作成します。 awaitではなく、はUIをブロックすることに注意してください。

private string Generate() 
{ 
    var sb = new StringBuilder(); 
    //TODO: Create the text with a StringBuilder as shown above. 
    return sb.ToString(); 
} 

private async Task<string> GenerateAsync() 
{ 
    return await Task.Run(() => Generate()); 
} 

// Don't forgat the async keyword in button1_Click! 
private async void button1_Click(object sender, EventArgs e) 
{ 
    label6.Text = "Generating Code.. Please wait...."; 

    string text = await GenerateAsync(); 

    textBox2.Text = text; 
    label6.Text = "Done."; 
} 
+0

ボタンをクリックした後、ボタンをクリックした後に "コードを生成しています...しばらくお待ちください...."と表示したい場合、OPが文字列ビルダを使用していない場合、ラベル6は "完了"と表示されるべきです – user3398379

+0

、textBox5 .Textはint.MaxValueに何かを含めることができますが、これは長時間実行される計算になるかもしれません:)なぜ私たちはこれをdupehammerしないのですか?スレッド間の呼び出しの欠落が原因で例外が発生していることは明らかです。 – dlatikay

+0

テキストは読み込み可能でなければならず、サイズは限られています。 –