2017-12-18 3 views
0

안녕 내가 버튼을생성 코드는

I를 제출 누를 때 나랑에 필요한 코드를 얻을 수 윈도우 폼 응용 프로그램에서 프로그램이 UI를 차단하지 그것을 설정하고 싶어 만든 창 형태로 제대로 작동하지 않습니다 내가 InvalidOperationException이이 처리되지 않은 예외가 얻을 암튼 이러한 코드 ..

다음

내가

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

시도를이 버튼 클릭 이벤트

,536,913되어 사용
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 [I가 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

버튼을 클릭 한 후 "레이블 6에 기다려주십시오."라는 메시지가 나타나기를 원합니다. OP가 stringbuilder를 사용하지 않고 label6이 "완료"로 표시되어야합니다 (예 : – user3398379

+0

). .Text는'int.MaxValue'에 무엇이든 포함 할 수 있습니다. 이것은 장시간의 계산으로 간주 될 수 있습니다 :) 왜 우리는 이것을 dupehammer로하지 않습니까? 누락 된 크로스 스레드 호출로 인해 예외에 관한 것이 분명합니다. – dlatikay

+0

텍스트는 읽을 수 있어야합니다. 즉, 크기가 제한되어 있어야합니다. –

관련 문제