이 메서드는 백그라운드에서 실행되며 원래 동기 메서드의 실제 작업을 수행합니다. 이 예제에서는 원래 메서드와 다르지 않습니다. 이 메서드에 대한 대리자 정의도 제공합니다. 이렇게 하면 동일한 형식을 가진 대리자 변수와 이벤트가 만들어집니다. 이벤트에 대한 액세스는 이벤트 선언에 의해 결정되므로(예: 위의 예제에서는 공용 이벤트를 생성합니다) 대리자 변수는 항상 비공개입니다. 이벤트의 암시적 본문은 대리자 변수에 대리자 인스턴스를 추가/제거할 수 있는 명백한 본문이지만 잠금 내에서 변경됩니다. C # 1.1의 경우 이벤트는 다음과 같습니다 : BeginInvoke () 및 EndInvoke ()가 아직 명확하지 않은 경우 곧 예제를 볼 수 있으므로 걱정하지 마십시오. 이번에는 거의 모든 작업이 스레드 풀 스레드에서 수행됩니다. 주 스레드는 비동기 작업을 시작하고 모든 작업이 완료될 수 있을 만큼 오랫동안 절전 모드로 끝납니다. 스레드 풀 스레드는 백그라운드 스레드입니다 – 추가 Sleep 호출없이 대리자 호출실행이 완료되기 전에 응용 프로그램이 종료됩니다. 일부 샘플 출력은 아래와 같습니다 – EndInvoke에 대한 호출에 대한 보장된 순서가 없기 때문에 이번에는 카운터 결과 앞에 파서 결과가 표시됩니다.

이전 예제에서는 파서가 카운터가 완료되기 전에 거의 확실하게 완료되었지만 주 스레드는 카운터의 결과를 먼저 얻기 위해 기다렸습니다. 참고: 이전 예제에서는 스레드가 안전하지 않은 두 개의 서로 다른 스레드에서 부울 변수를 사용했습니다. 그러나 이러한 공유 변수를 사용하는 것은 여러 스레드 간에 공유 할 수있는 데이터가 잠겨 있는지 확인하는 것입니다. 이제 보조 스레드가 Add() 작업을 완료하면 EndInvoke()를 호출할 위치가 어디입니까? 그럼 당신은 두 곳에서 EndInvoke를 호출 할 수 있습니다. 이미지를 비동기적으로 엠보싱하기 위해 프로그램은 Emboss 메서드를 나타내는 대리자를 만듭니다. 다음 코드는 대리자의 선언을 보여 주며, 이는 이전 예제에서 사용한 대리자와 동일합니다. 대리자 인스턴스가 문자열 또는 숫자인 것처럼 두 대리자 인스턴스를 결합하는 작업은 일반적으로 추가 연산자를 사용하여 수행됩니다. 다른 하나에서 하나를 빼는 것은 일반적으로 빼기 연산자로 수행됩니다.

결합된 대리자를 다른 대리자에서 빼면 빼기는 목록 측면에서 작동합니다. 빼는 목록이 원래 목록에서 찾을 수 없는 경우 결과는 원래 목록일 뿐입니다. 그렇지 않으면 목록의 마지막 발생이 제거됩니다. 다음은 몇 가지 예제와 함께 표시되는 것이 가장 좋습니다. 다음은 실제 코드 대신 간단한 대리자 d1, d2 등의 목록을 사용합니다. 예를 들어 [d1, d2, d3]는 결합된 대리자로, 실행될 때 d1을 호출한 다음 d2를 호출한 다음 d3를 호출합니다. 빈 목록은 실제 대리자 인스턴스가 아닌 null로 표시됩니다. 이 예제에서는 스레드가 완료될 때까지 기다리는 대신 콜백을 사용합니다. 이렇게 하면 다른 스레드가 작동하는 동안 UI 스레드의 응답성을 유지할 수 있습니다. 콜백은 ThreadPool 스레드에서 이루어집니다.

ThreadPool 스레드는 기본 스레드가 종료되는 경우 응용 프로그램을 계속 실행하지 않는 백그라운드 스레드이므로 예제의 주 스레드는 콜백이 완료될 수 있을 만큼 충분히 오래 절전 모드로 유지됩니다. 이전 기사에서는 대리자를 사용하여 메서드를 비동기적으로 호출한 다음 다중 스레딩 환경에서 스레드 동기화에 대해 설명했습니다. 이전 코드 예제에서는 BeginInvoke() 메서드를 사용하여 비동기 호출을 했습니다. 다음 코드 예제에서는 TestMethod의 정의 및 TestMethod를 비동기적으로 호출하는 데 사용할 수 있는 AsyncMethodCaller라는 대리자입니다. 코드 예제를 컴파일하려면 TestMethod 및 AsyncMethodCaller 대리자에 대한 정의를 포함해야 합니다. 대리자 인스턴스에서 참조하는 메서드는 대상 개체(있는 경우)에서 호출되고 결과가 반환됩니다. 겉보기에 관련이없는 코드를 많이 포함하지 않고 이를 설명하는 완전한 프로그램을 제작하는 것은 까다롭습니다.