2011-05-02 5 views
0

2 개의 스레드 (fpDoWork)를 처리하는 1 클래스 (acBL)가 있습니다. fpDoWork에서 수행되는 작업은 acBL 클래스로 다시 이벤트를 트리거합니다. 내 양식에서 acBL 클래스를 선언하고 acBL에 이벤트 핸들러를 연결합니다.이 방법은 이벤트가 호출 될 때마다 UI를 변경 사항으로 업데이트해야합니다.스레드가 완료 될 때까지 BeginInvoke를 사용하여 UI 업데이트가 중단 되었습니까?

각 fpDoWork 스레드가 시작될 때마다 처리 작업이 수행되고 ProcessingEvent가 호출되고 frmMain.handlerProcessing1 이벤트로 넘어갑니다. this.BeginInvoke (new Processing2Event (handlerProcessing2), status)가 호출 된 지점에 도달하면 UI가 계속 업데이트되기 전에 스레드가 작업을 마칠 때까지 대기하고 대기합니다. 나는 이것을 시도했다 .Invoke. 그러나 그 방법은 매달리는 것처럼 보인다. 어떤 아이디어?

this.acBL.Processing1Event += new acBL.Processing1(handlerProcessing1); 
this.acBL.Processing2Event += new acBL.Processing2(handlerProcessing2); 

핸들러 :

private void handlerProcessing1(string status) { 
    if (InvokeRequired) { 
    this.BeginInvoke(new MethodInvoker(this.Refresh)); 
    this.BeginInvoke(new Processing1Event (handlerProcessing1), status); 

    } 
    else { 
    Console.WriteLine("UPDATING 1: "+status); 
    lblForProcessing1.Text = status; 
    this.Refresh(); 
    return; 
    } 
} 


private void handlerProcessing2(string status) { 
    if (InvokeRequired) { 
    this.BeginInvoke(new MethodInvoker(this.Refresh)); 
    this.BeginInvoke(new Processing2Event (handlerProcessing2), status); 

    } 
    else { 
    Console.WriteLine("UPDATING 2: "+status); 
    lblForProcessing2.Text = status; 
    this.Refresh(); 
    return; 
    } 
} 

코드 ACBL

내부의 주요 방법은 :

bool thread1Complete = false; 
fpDoWork fpDoWork1 = new fpDoWork(); 
fpDoWork1.GUIForm = frmMain; 
fpDoWork1.ProcessingEvent += new fpDoWork.Processing(handlerProcessing1Event); 
fpDoWork1.ThreadCompleteEvent += new fpDoWork.ThreadComplete(thread1Complete); 
Thread fpDoWork1Thread= new Thread(new ThreadStart(fpDoWork1.StartWork)); 

bool thread2Complete = false; 
fpDoWork fpDoWork2 = new fpDoWork(); 
fpDoWork2.GUIForm = frmMain; 
fpDoWork2.ProcessingEvent += new fpDoWork.Processing(handlerProcessing2Event); 
fpDoWork2.ThreadCompleteEvent += new fpDoWork.ThreadComplete(thread2Complete); 
Thread fpDoWork2Thread= new Thread(new ThreadStart(fpDoWork2.StartWork)); 

Console.WriteLine("Work for 1 Thread started..."); 
fpDoWork1Thread.Start(); 
Console.WriteLine("Work for 2 Thread started..."); 
fpDoWork2Thread.Start(); 

while (!thread1Complete && !thread2Complete) { 
    if (!thread1Complete && !thread2Complete) { 
    Console.WriteLine("Waiting for both copying threads..."); 
    } 
    else if (!thread1Complete && thread2Complete) { 
    Console.WriteLine("Waiting for thread 1..."); 
    } 
    else if (thread1Complete && !thread2Complete) { 
    Console.WriteLine("Waiting for thread 2..."); 
    } 
    Thread.Sleep(1000); 
} 
Console.WriteLine("All done"); 
01,235

이전 코드에서 frmMain 수 내부

코드 그렇지 16,

어디 코드 :

public delegate void ProcessingFor1 (string filename); 
public delegate void ProcessingFor2 (string filename); 
public event ProcessingFor1 ProcessingEventFor1; 
public event ProcessingFor2 ProcessingEventFor2; 


private void handlerProcessing1Event(string filename) { 
    Console.WriteLine("Processing 1: " + filename); 
    ProcessingEventFor1(filename); 
} 

private void handlerProcessing1Event(string filename) { 
    Console.WriteLine("Processing 2: " + filename); 
    ProcessingEventFor2(filename); 
} 
+2

당신은에 의해 교착 상태를 만드는 UI 스레드를 차단하고 플래그를 반복합니다. BeginInvoke 대상은 UI 스레드가 유휴 상태가 될 때까지 다시 실행할 수 없으며 메시지 루프를 펌핑합니다. 결코 UI 스레드를 차단해서는 안됩니다. 재발견을 피하기 위해 BackgroundWorker를 사용하십시오. 그리고 IsBusy 속성에도 동일한 문제가 발생하지 않도록합니다. 스레드가 RunWorkerCompleted 이벤트 처리기에서 완료된 후에 원하는 작업을 수행하십시오. –

+0

BackgroundWorker를 통합하기 위해 코드를 다시 작성할 시간이 없습니다. 전에 구현하려고 시도했지만 제한 사항을 발견했습니다. 이 시나리오에서 교착 상태를 수정할 수있는 방법이 있습니까? – user723217

+0

한스의 의견이 정확합니다. 교착 상태 수정에는 시간이 걸립니다. 나는 그것을 올바르게 고치기위한 시간을 투자한다는 그의 움직임을 두 번째로 말한다. 해킹 된 솔루션 (예 : 중첩 된 메시지 루프)은 앞으로 처리 할 수있는 이상한 버그를 일으킬뿐입니다. 그것은 나중에 시간 대신에 일찍 그것을 고치는 많은 시간을 절약 할 수 있습니다. –

답변

0

당신의 UI가 업데이트되지 않는 이유는 기본 UI 스레드가 동안() 루프에 갇혀 있다는 것입니다. BackgroundWorker에

환호를 하나 개의 스레드에서 스레드를 생성 방지하고 처음부터 그들을 종료 될 때까지 대기가 스레드의 나쁜 사용을 앉아 친구

시도이다

관련 문제