2012-07-27 5 views
-2

텍스트 상자에 내용을 비동기 적으로 표시하고 싶습니까? 누구든지 내 코드의 버그를 알고 있습니까? 나는 새로운 값으로 초당 업데이트 될 텍스트 상자에 텍스트를 구현하고 싶습니까? 또한 나는 왜 InvokeRequired를 호출 할 때마다 매번 Invoke 메소드를 호출 할까?텍스트 상자의 내용 비동기

 private void Counting(int Num) 
    { 

     int i = 0; 
     string counter = null; 
     while (i < Num) 
     { 
      Thread.Sleep(1000); 
      counter = string.Format(" {0}", i); 
      tbxStatus.BeginInvoke(new UpdateStatusDelegate(UpdateStatus), new string[] { counter }); 
     } 

    } 

    public void UpdateStatus(string data) 
    { 
     tbxStatus.Text += data; 
    } 

    public delegate void UpdateStatusDelegate(string data); 

    public delegate void CountDelegate(int num); 

    private void btnStart_Click(object sender, EventArgs e) 
    { 
     if (this.InvokeRequired) 
     { 
      this.Invoke(new CountDelegate(Counting), new object[] { 5 }); 
     } 
     else 
      Counting(5); 
    } 

감사

답변

1

귀하의 InvokeRequired 테스트는 위임 안에 있어야한다 :

public void UpdateStatus(string data) 
{ 
    if (this.tbxStatus.InvokeRequired) 
    { 
     UpdateStatusDelegate d = new UpdateStatusDelegate(UpdateStatus); 
     this.Invoke(d, new object[] { data }); 
    } 
    else 
    { 
     this.tbxStatus.Text = data; 
    } 
} 

당신은이 훨씬 쉽게 만들 수 있으며, 다음과 같은 확장 방법을 사용하는 경우 청소기 찾고 :

public static TResult SafeInvoke(this T isi, Func call) where T : ISynchronizeInvoke 
{ 
    if (isi.InvokeRequired) { 
     IAsyncResult result = isi.BeginInvoke(call, new object[] { isi }); 
     object endResult = isi.EndInvoke(result); return (TResult)endResult; 
    } 
    else 
     return call(isi); 
} 

public static void SafeInvoke(this T isi, Action call) where T : ISynchronizeInvoke 
{ 
    if (isi.InvokeRequired) isi.BeginInvoke(call, new object[] { isi }); 
    else 
     call(isi); 
} 

그래서 내가 정의한 메소드를 호출하려면 (양식 인스턴스에 정의 된 방법 등) 내 UI 스레드 당신이 (모든 대의원 또는 아무것도 생성 할 필요없이) 다음 코드를 사용하여 수행 할 수 있습니다 : 귀하의 경우

formInstance.SafeInvoke(f => f.myFormMethod("parameter1","parameter2")); 

, 당신은 다음 작업을 수행 할 수 있습니다 :

formInstance.SafeInvoke(f => f.UpdateStatus(myCounterInt.toString)); 

등등.

나는이 on my blog 사용에 대한 작성한하지만 난에 대한 this CodeProject article

1

내가 최근에 비슷한 문제에왔다 기록 된대로 나에게 신용을 제공하지 않습니다.

네트워크로 연결된 게임을 작성하고 텍스트 상자에 텍스트를 추가하고 싶지만 다른 폼의 Windows 폼 컨트롤을 변경하려고 시도하는 오류가 발생하여 안전하지 않은 스레드가 발생합니다 . 이는 내 서버 측에서 ASyncCallback을 사용하기 때문입니다.

나는 이전에 이렇게했다 : (콘솔 메서드는 문자열을 가져 와서 텍스트 상자에 추가하는 간단한 메서드이다).

console("message"); 

그리고 지금은 문제 해결이로 변경 한 문제를 해결하기 :

this.Invoke((MethodInvoker)delegate { console("message"); }); 

는 희망이이 문제를 건너 다른 사람을 도움이됩니다. 그것은 아마도 최선의 접근법이 아니지만 그것은 나를 위해 트릭을했습니다.

감사합니다.

관련 문제