0

hi i made a program in windows form application to get a code which is needed for me.I wanted to set it for not blocking UI when i press submit button

I used these code for that.But i get invalidoperationexception was unhandled exception..

Here i tried

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;
        }
    }
}

This is the button click event

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....";
}
Olivier Jacot-Descombes
  • 104,806
  • 13
  • 138
  • 188
user3398379
  • 83
  • 1
  • 8

1 Answers1

2

Only the UI thread can update the UI. It makes sense to run time consuming I/O operations or long running calculations in another thread; however, it makes no sense to run a method that basically only updates textboxes in another thread. This method would have to call Invoke on the textboxes, making the textbox operations run on the UI thread again.

Simply run this method normally in the click event.

You can speed up the method by using a StringBuilder and by assigning to the textbox only once:

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();

Strings are immutable. Concatenating strings repeatedly is not efficient as a new string object is created each time and the content of the old string object is copied to the new one + the new text. On the other hand, a StringBuilder works with an internal string buffer that can grow until its max capacity is reached. Then it creates a lager buffer and copies the text of the old butter to the new buffer. This new buffer has plenty of free space, so that many new text pieces can be appended, before a new resize operation must be performed.

Assigning to the same textbox repeatedly is time consuming, as the textbox also triggers events. Only assigning the final text once, speeds up the things further.

I think, like this, it will be fast enough without multithreading. If it should not be, I would make a method that does only create the string and use it to create a task that can be awaited. Note that await does not block the 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.";
}
Olivier Jacot-Descombes
  • 104,806
  • 13
  • 138
  • 188
  • I want to show "Generating Code.. Please wait....in label 6" after clicking the button and after finishing the Generate method label6 should be showed as "Done" – user3398379 Dec 18 '17 at 21:00
  • given that OP is not using a stringbuilder, and textBox5.Text can contain anything to `int.MaxValue`, this may qualify as a long running calculation :) why we don't just dupehammer this? it is clearly about the exception due to missing cross-thread invoke. – Cee McSharpface Dec 18 '17 at 21:06