2010-03-01 3 views
3

응용 프로그램 시작시 채워야하는 Janus 표 컨트롤이 여러 개 있습니다.WinForms Control.BeginInvoke 비동기 콜백

시작 시간과 이러한 그리드를 새로 고치는 데 걸리는 시간을 단축하기 위해이 그리드를 다른 스레드에로드하고 싶습니다. 각 그리드는 별도의 탭에 있습니다. 이상적으로는 각 그리드에서 Control.BeginInvoke를 사용하고 그리드로드에서 탭을 완료하면 사용 가능하게됩니다.

BeginInvoke를 사용할 때 대리자를 사용하면 비동기 콜백을 수행 할 수 있으므로 비동기 콜백의 탭을 활성화 할 수 있지만 Control.BeginInvoke를 사용할 때는 불가능합니다. Control.BeginInvoke 또는 더 나은 솔루션을 사용하여 비동기 콜백을 수행하는 방법이 있습니까?

지금까지 내가 가진 :

public delegate void BindDelegate(IMyGrid grid); 

private IAsyncResult InvokeBind(IMyGrid grid) 
{ 
    return ((Control)grid).BeginInvoke(
    new BindDelegate(DoBind), new object[] { grid } 
); 
} 

private void DoBind(IMyGrid grid) 
{ 
    grid.Bind(); // Expensive operation 
} 

private void RefreshComplete() 
{ 
    IAsyncResult grid1Asynch = InvokeBind(grid1); 
    IAsyncResult grid2Asynch = InvokeBind(grid2); 
    IAsyncResult grid3Asynch = InvokeBind(grid2); 
    IAsyncResult grid4Asynch = InvokeBind(grid3); 
    IAsyncResult grid5Asynch = InvokeBind(grid4); 
    IAsyncResult grid6Asynch = InvokeBind(grid5); 
} 

지금은 별도의 스레드를 분사하고 IAsynchResults가 완료에 따라 하나의 내가있는 탭 컨트롤을 다시 활성화 할 수 완료했는지 확인하기 위해 계속 확인 할 수있는 그리드가 포함되어 있습니다.이 작업을 수행하는 더 좋은 방법이 있습니까?

답변

1

Control (모든 표준 및 확장 WinForms 컨트롤을 포함하는 인스턴스)의 직접 조작은 해당 컨트롤이 만들어진 스레드에서 수행해야합니다. 윈도우 GUI는 쓰레드에 안전하지 않다. 실제로 생성 된 각 윈도우 (그리고 대부분의 컨트롤은 적어도 하나를 생성 할 것이다)는 쓰레드 친 화성을 갖는다.

일반적으로 Control.BeginInvoke은 GUI 스레드에서 일부 작업을 수행하기 위해 다른 스레드에서 사용되므로 속성을 올바르게 읽거나 설정할 수 있습니다.

그리드를 채울 데이터를 얻기 위해 스레드 풀에서 작업 항목을 확실히 스핀 업할 수 있지만 GUI 스레드에서 그리드 (데이터 바인딩 포함)의 실제 구성 및 채우기를 수행해야합니다. 데이터를 얻는 데 시간이 걸리면 좋은 생각입니다. 그러나 응답 성이 좋은 GUI를 얻을 수 있기 때문에 모두 함께 사용하면 —이 데이터 소스의 경합으로 인해 모두 한 번에 비해 느려질 수 있습니다.

+0

채우기 전후에 'SuspendLayout()'및 'ResumeLayout (false)'를 사용하면 그리드가 즉각적인 상태로 그려지지 않을 수도 있습니다. – Oliver

관련 문제