Xamarin.iOS에서 스레딩

Xamarin.iOS 런타임은 개발자가 스레드System.Threading.Thread, System.Threading.ThreadPool()를 사용할 때 명시적으로, 그리고 비동기 대리자 패턴 또는 BeginXXX 메서드를 사용하는 경우와 작업 병렬 라이브러리를 지원하는 전체 API 범위를 사용할 때 암시적으로 .NET 스레딩 API에 액세스할 수 있도록 합니다.

Xamarin은 다음과 같은 몇 가지 이유로 애플리케이션을 빌드하기 위해 TPL(작업 병렬 라이브러리)을 사용하는 것이 좋습니다.

  • 기본 TPL 스케줄러는 태스크 실행을 스레드 풀에 위임합니다. 그러면 프로세스가 수행될 때 필요한 스레드 수가 동적으로 증가하지만 너무 많은 스레드가 CPU 시간 동안 경쟁하게 되는 시나리오를 방지합니다.
  • TPL 작업 측면에서 작업에 대해 더 쉽게 생각할 수 있습니다. 쉽게 조작하거나, 예약하거나, 실행을 직렬화하거나, 다양한 API 집합과 병렬로 여러 API를 실행할 수 있습니다.
  • 새 C# 비동기 언어 확장을 사용한 프로그래밍의 기초입니다.

스레드 풀은 시스템에서 사용할 수 있는 CPU 코어 수, 시스템 로드 및 애플리케이션 요구 사항에 따라 필요에 따라 스레드 수를 서서히 증가합니다. 메서드를 System.Threading.ThreadPool 호출하거나 기본값 System.Threading.Tasks.TaskScheduler (병렬 프레임워크의 일부)을 사용하여 이 스레드 풀을 사용할 수 있습니다.

일반적으로 개발자는 반응형 애플리케이션을 만들어야 하는 경우 스레드를 사용하며 기본 UI 실행 루프를 차단하지 않습니다.

반응형 애플리케이션 개발

UI 요소에 대한 액세스는 애플리케이션에 대한 기본 루프를 실행하는 동일한 스레드로 제한되어야 합니다. 스레드에서 기본 UI를 변경하려면 다음과 같이 NSObject.InvokeOnMainThread를 사용하여 코드를 큐에 추가해야 합니다.

MyThreadedRoutine ()  
{  
    var result = DoComputation ();  

    // we want to update an object that is managed by the main
    // thread; To do so, we need to ensure that we only access
    // this from the main thread:

    InvokeOnMainThread (delegate {  
        label.Text = "The result is: " + result;  
    });
}

위의 코드는 잠재적으로 애플리케이션이 충돌할 수 있는 경합 조건을 일으키지 않고 기본 스레드의 컨텍스트에서 대리자 내의 코드를 호출합니다.

스레딩 및 가비지 수집

실행 과정에서 런타임은 개체를 Objective-C 만들고 해제합니다. 개체에 "자동 릴리스" Objective-C 에 플래그가 지정된 경우 런타임은 해당 개체를 스레드의 현재 NSAutoReleasePool상태로 해제합니다. Xamarin.iOS는 기본 스레드의 System.Threading.ThreadPool 모든 스레드에 대해 하나의 NSAutoRelease 풀을 만듭니다. 이 확장은 System.Threading.Tasks에서 기본 TaskScheduler를 사용하여 만든 모든 스레드를 다룹니다.

사용자 System.Threading 고유의 스레드를 만드는 경우 데이터가 누출되지 않도록 자체 NSAutoRelease 풀을 제공해야 합니다. 이렇게 하려면 다음 코드에서 스레드를 래핑하기만 하면 됩니다.

void MyThreadStart (object arg)
{
   using (var ns = new NSAutoReleasePool ()){
      // Your code goes here.
   }
}

참고: Xamarin.iOS 5.2는 자동으로 제공되므로 더 이상 직접 NSAutoReleasePool 제공할 필요가 없습니다.