솔직히 솔직히 말하면 조금 실망 스럽습니다;) 그래서 약간의 도움을 요청합니다.서브 스레드와 메인 스레드 동기화하기 - 명백한 문제가 아닙니다.
일부 차트를 그릴 수있는 몇 가지 종류의 컨트롤이 있다고 가정 해 봅시다. 이 컨트롤에 차트를 그리는 방법도 있습니다. 문제는 차트 메서드가 컨트롤 필드 중 하나에만 액세스 할 수 있으므로 차트가 준비되면 컨트롤을 새로 고쳐야한다는 것입니다.
그럼 우리의 통제가 보이는 가정 해 봅시다 : Canvas
이미지 (그래픽 같은)을 그리는 데 사용하는 클래스입니다
class ChartingControl : System.Windows.Forms.Control
{
public Canvas canvas;
public void Refresh();
/*
... other fields/methods
*/
}
.
차트 작성 방법 만 canvas
객체 (우리는 변경할 수 없습니다)에 액세스 할 수있는, 그래서 그 모양 :이 방법은 등 별도의 스레드, 배경 노동자에서 호출 할 수
public static void DrawChart(canvas)
{ /* draw */ }
... 그리고 차트가 준비되면 기본 스레드와 동기화하고 Refresh()
으로 호출해야합니다. 차트가 준비되면
는 지금, 나는 캔버스 객체
public static void DrawChart(canvas)
{ /* draw */
canvas.Tag = true; // chart is ready
}
에 플래그를 설정 그리고 나는 배경 작업자가 차트 컨트롤의 내부 실행하고 canvas.Tag
필드가 변경된 경우, 듣기, 그렇다면이 그것은 Refresh()
그러나 내 방법은 약간 거친 것 같고, 쉽게 실패하는 등 ... 어떤 개선 된 방법이 있습니까?
제한 사항 :
- Canvas
클래스는 수정할 수 없습니다. 우리가 사용할 수있는 유일한 방법은 (유형 object
의 Tag
필드 - 우리가 ChartingControl
클래스와 그리기 방법을 수정할 수 있습니다
-. 많은 차트 컨트롤의
가있을 수 있습니다 -. 우리는 DrawChart
가 호출 방식을 제어 할 수 없다는 그것은 수 별도의 스레드에서 호출, 또는하지 수. 그것은 다른 곳이라고합니다. 우리가 할 수있는 모든 컨트롤과 DrawChart 방법을 만들고 어떻게 든 그들을 comunicate 수하는 것입니다
해결책
OK, 나는 이런 식으로 해결 : ChartingControl
에서 나는 ManualResetEvent manualReset
과 배경 작업자를 만들었습니다.
void backgroundWorker_DoWork(object sender, System.ComponentModel.DoWorkEventArgs e)
{
manualReset.WaitOne(); // Wait for a chart to be ready
}
및 차트 때 결국
void backgroundWorker_RunWorkerCompleted(object sender, System.ComponentModel.RunWorkerCompletedEventArgs e)
{
Refresh();
}
내가 canvas.Tag
내부 및 도면에있어서 내부 manualReset
객체를 전달 리셋() 메소드를 호출
배경이 작업자 manualReset
기다린다 준비 완료 manualReset.Set();
으로 전화하여 차트 준비 신호를 전달하십시오.
DrawChart 메서드가 새 스레드를 시작하거나 다른 스레드에서 호출합니까? –
다른 스레드에서 호출합니다 – Gacek