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);
}
당신은에 의해 교착 상태를 만드는 UI 스레드를 차단하고 플래그를 반복합니다. BeginInvoke 대상은 UI 스레드가 유휴 상태가 될 때까지 다시 실행할 수 없으며 메시지 루프를 펌핑합니다. 결코 UI 스레드를 차단해서는 안됩니다. 재발견을 피하기 위해 BackgroundWorker를 사용하십시오. 그리고 IsBusy 속성에도 동일한 문제가 발생하지 않도록합니다. 스레드가 RunWorkerCompleted 이벤트 처리기에서 완료된 후에 원하는 작업을 수행하십시오. –
BackgroundWorker를 통합하기 위해 코드를 다시 작성할 시간이 없습니다. 전에 구현하려고 시도했지만 제한 사항을 발견했습니다. 이 시나리오에서 교착 상태를 수정할 수있는 방법이 있습니까? – user723217
한스의 의견이 정확합니다. 교착 상태 수정에는 시간이 걸립니다. 나는 그것을 올바르게 고치기위한 시간을 투자한다는 그의 움직임을 두 번째로 말한다. 해킹 된 솔루션 (예 : 중첩 된 메시지 루프)은 앞으로 처리 할 수있는 이상한 버그를 일으킬뿐입니다. 그것은 나중에 시간 대신에 일찍 그것을 고치는 많은 시간을 절약 할 수 있습니다. –