위와 같은 문제점을 해결하기 위해 쓰레드 함수에서 UI 컨트롤을 엑세스할 때, 항상
Control클래스의 InvokeRequired 속성을
체크하여 현재 쓰레드로 컨트롤을 엑세스할 수 있는지를 검사해야 한다. 만약 InvokeRequired값이 true이면,
현재 쓰레드는 Worker Thread라는 뜻이므로, Invoke(동기 호출)나 BeginInvoke(비동기 호출)를 사용하여 UI Thread로 메서드 호출을 보내야 한다. (참조:
UI Thread)
아래 예제는 위의 예제중 ShowProgress부분을 고쳐쓴 것으로, InvokeRequired 속성을 체크하여 필요한 경우 (Invoke를 호출하여) UI Thread로 돌려 보내는 예이다. 여기서의 동기 호출을 위한 Invoke()에는
어뗜 함수를 호출할지를 지정하는 Delegate객체와 그 함수가 사용할 파라미터(pct)를 전달하고 있다.
예제
delegate void ShowDelegate(int percent);
private void ShowProgress(int pct)
{
if (InvokeRequired)
{
ShowDelegate del = new ShowDelegate(ShowProgress);
//또는 ShowDelegate del = p => ShowProgress(p);
Invoke(del, pct);
}
else
{
progressBar1.Value = pct;
}
}