PCL 사례 연구: Microsoft TPL 데이터 흐름 NuGet 패키지용 System.Diagnostics.Tracing과 관련된 문제를 해결하려면 어떻게 할까요?

Important

이 특정 예제에서는 System.Diagnostic.Tracing 최신 버전의 Xamarin에서 더 이상 오류를 생성하지 않습니다. 제안된 해결 방법은 여전히 작동하지만 "오류 계층" 섹션에 멘션 일부 버그가 수정되었습니다. 또한 .NET Standard는 이제 플랫폼 간 .NET API를 구현하는 기본 방법입니다.

요약

Xamarin.iOS 및 Xamarin.Android는 참조로 허용되는 모든 PCL 프로필을 100% 구현하지 않습니다. Mac용 Visual Studio, Visual Studio 및 NuGet 패키지 관리자의 실질적인 편의를 위해 Xamarin 프로젝트는 불완전한 구현만 있는 여러 프로필을 사용할 수 있도록 합니다. 예를 들어 Xamarin.iOS와 Xamarin.Android 모두 현재 "System.Diagnostics.Tracing" PCL 네임스페이스에 형식의 완전한 구현이 포함되어 있지 않습니다. 이 제한으로 인해 Microsoft TPL Dataflow NuGet 패키지의 기본 portable-net45+win8+wpa81 버전을 사용하려고 할 때 세 가지 오류 계층이 발생합니다.

해결 방법: TPL 데이터 흐름 라이브러리의 버전을 참조 portable-net45+win8+wp8+wpa81 하도록 앱 프로젝트 전환

(이렇게 하면 세 계층의 오류가 모두 방지되고 모든 최신 버전의 Xamarin에서 작동합니다.)

  1. 텍스트 편집기에서 애플리케이션 프로젝트 .csproj 파일을 엽니다.

  2. 다음과 유사한 줄을 찾습니다.

    <HintPath>..\packages\Microsoft.Tpl.Dataflow.4.5.24\lib\portable-net45+win8+wpa81\System.Threading.Tasks.Dataflow.dll</HintPath>
    
  3. 변경 portable-net45+win8+wpa81 내용 portable-net45+win8+wp8+wpa81 (+wp8 추가됨):

    <HintPath>..\packages\System.Threading.Tasks.Dataflow.4.5.25\lib\portable-net45+win8+wp8+wpa81\System.Threading.Tasks.Dataflow.dll</HintPath>
    

설명

portable-net45+win8+wp8+wpa81 라이브러리 버전은 System.Diagnostics.Tracing.dll전혀 참조하지 않으므로 세 계층의 문제를 완전히 방지합니다.

제한 사항

  • portable-net45+win8+wp8+wpa81 라이브러리 버전에는 버전 기능 portable-net45+win8+wpa81 의 100%가 포함되지 않을 수 있습니다.

  • NuGet 패키지 관리자는 기본적으로 PCL NuGet 패키지 버전을 설치 portable-net45+win8+wpa81 하므로 직접 참조를 조정해야 합니다.

세 가지 오류 계층에 대한 세부 정보

  1. System.Diagnostics.Tracing.dll 외관 어셈블리는 현재 모든 Mac 버전의 Xamarin.Android(비공용 버그 34888)에 없으며 9.0보다 낮거나 Windows의 XamarinVS 3.11.1443보다 낮은 모든 Xamarin.iOS 버전(버그 32388에서 수정됨)이 없습니다. 이 문제로 인해 배포 대상 및 링커 설정에 따라 다음 오류 중 하나가 발생합니다.

    • Xamarin.Android.Common.targets: 오류: 어셈블리를 로드하는 동안 예외: System.IO.FileNotFoundException: 'System.Diagnostics.Tracing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a' 어셈블리를 로드할 수 없습니다. Android용 Mono 프로필에 존재하지 않나요?

    • 파일 또는 어셈블리 'System.Diagnostics.Tracing' 또는 해당 종속성 중 하나를 로드할 수 없습니다. 시스템은 지정된 파일을 찾을 수 없습니다. (System.IO.FileNotFoundException)

    • MTOUCH: 오류 MT3001: '/Users/macuser/Projects/TPLDataflow/UnifiedSingleViewIphone1/obj/i전화/Debug/mtouch-cache/64/Build/System.Threading.Tasks.Dataflow.dll' 어셈블리를 AOT할 수 없습니다.

    • MTOUCH: 오류 MT2002: 어셈블리를 해결하지 못했습니다. 'System.Diagnostics.Tracing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a'

  2. "System.Diagnostics.Tracing"의 형식에 대한 현재 Mono 구현에는 일부 메서드 오버로드가 없습니다. 이 문제로 인해 Xamarin 앱을 빌드할 때 다음 링커 오류 중 하나가 발생합니다.

    • /Library/Frameworks/Mono.framework/External/xbuild/Xamarin/Android/Xamarin.Android.Common.targets: error : Error executing task LinkAssemblies: error XA2006: Reference to metadata item 'System.Void System.Diagnostics.Tracing.EventSource::WriteEvent(System.Int32,System.Object[])' (defined in 'System.Threading.Tasks.Dataflow, Version=4.5.24.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a') from 'System.Threading.Tasks.Dataflow, Version=4.5.24.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a'를 확인할 수 없습니다.

    • MTOUCH: 오류 MT2002: "System.Diagnostics.Tracing.EventSource::WriteEvent(System.Int32,System.Object[])" 참조를 "System.Diagnostics.Tracing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a"에서 해결하지 못했습니다.

  3. "System.Diagnostics.Tracing"의 형식에 대한 현재 Mono 구현도 현재 "더미" 구현입니다(버그 34890). 따라서 런타임에 이러한 메서드를 사용하려고 시도하면 예기치 않은 결과가 발생할 수 있습니다. Microsoft TPL 데이터 흐름 라이브러리의 특정 사례에서는 대부분의 라이브러리 동작에 대한 호출 WriteEvent(System.Int32,System.Object[]) 이 필수적이지 않은 것 같으므로 대부분의 Microsoft TPL 데이터 흐름 사용 사례에서는 "계층 2"(버그 27337, 빈 구현 추가)에 대한 수정 사항으로 충분할 수 있습니다.

질문과 대답

이전 버전의 Xamarin.iOS 또는 Xamarin.Android에서 라이브러리 버전으로 portable-net45+win8+wpa81 연결을 사용하도록 설정할 수 있었습니다. 어떻게 작동했습니까?

답변

외관 어셈블리 [2]가 아닌 참조 어셈블리 [1]에 대한 참조System.Diagnostics.Tracing.dll를 포함하는 경우 이전 버전의 Xamarin.iOS 또는 Mac의 Xamarin.Android에서 빌드가 "성공적으로"(연결 사용) 완료되도록 할 수 있지만 불행히도 이것은 "올바른" 해결 방법이 아닙니다. 참조 어셈블리는 앱과 같은 플랫폼별 코드가 아니라 이식 가능한 라이브러리를 빌드할 때만 사용됩니다. 참조 어셈블리에 포함된 코드를 실행하려고 하면(빌드가 아닌) 예기치 않은 결과가 발생할 수 있습니다. 올바른 수정 사항은 Mono 팀이 누락된 WriteEvent(System.Int32,System.Object[]) 오버로드 EventSource 를 형식에 추가하는 것입니다(버그 27337). 지금은 위의 해결 방법 섹션에서 설명한 대로 Microsoft TPL 데이터 흐름 라이브러리 버전으로 전환하는 portable-net45+win8+wp8+wpa81 것이 가장 좋습니다.

(StackOverflow(https://stackoverflow.com/a/23591322/2561894)에서 관련 이전의 간략한 대답을 본 후 이 문서를 읽을 수 있는 모든 사용자를 위해 참조 어셈블리와 외관 어셈블리 간의 구분이 멘션 없습니다.)

[1] "참조 어셈블리" 위치

Windows: C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETPortable\v4.5\System.Diagnostics.Tracing.dll

Mac(Mono): /Library/Frameworks/Mono.framework/Versions/Current/lib/mono/xbuild-frameworks/.NETPortable/v4.5/System.Diagnostics.Tracing.dll

[2] "외관 어셈블리" 위치

Windows: C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.5\Facades\System.Diagnostics.Tracing.dll

Mac(Mono): /Library/Frameworks/Mono.framework/Versions/Current/lib/mono/4.5/Facades/System.Diagnostics.Tracing.dll

"System.Diagnostics.Tracing" 외관 어셈블리에 대한 참조를 수동으로 추가하는 경우 도움이 되나요?

특히 이러한 2단계를 사용하여 문제를 해결할 수 있나요?

  1. System.Diagnostics.Tracing.dll 다음 위치 중 하나에서 외관 어셈블리를 애플리케이션 프로젝트 폴더에 복사합니다.

    Windows: C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.5\Facades\System.Diagnostics.Tracing.dll

    Mac(Mono): /Library/Frameworks/Mono.framework/Versions/Current/lib/mono/4.5/Facades/System.Diagnostics.Tracing.dll

  2. Xamarin.iOS 또는 Xamarin.Android 애플리케이션 프로젝트에서 외관 어셈블리에 대한 참조를 추가합니다.

답변

아니요, 도움이 되지 않습니다.

  • Xamarin.iOS 9.0 또는 Windows의 최신 버전의 Xamarin.Android의 경우 이 해결 방법은 엄격하게 중복되며 "동일한 ID를 가진 어셈블리 'System.Diagnostics.Tracing'이 이미 가져왔습니다."와 유사한 컴파일 오류가 발생할 수 있습니다.

  • Xamarin.iOS 8.10 이하 또는 Mac의 Xamarin.Android의 경우 이 해결 방법은 "계층 1" 누락 어셈블리 문제에만 도움이 됩니다. "계층 2" 링커 오류는 해결되지 않으므로 완전한 솔루션이 아닙니다.

System.Diagnostics.Tracing NuGet 패키지를 사용하여 문제를 해결할 수 있나요?

답변

아니요, NuGet 3.0 "System.Diagnostics.Tracing" 패키지에는 "DNXCore50" 및 "netcore50"에 대한 플랫폼별 구현만 포함됩니다. Xamarin.Android("MonoAndroid") 및 Xamarin.iOS("MonoTouch" 및 "xamarinios")에 대한 구현을 명시적으로 생략 합니다. 즉, 패키지를 설치해도 Xamarin.Android 및 Xamarin.iOS 프로젝트에는 영향을 주지 않습니다. NuGet 패키지는 두 플랫폼이 형식의 고유한 구현을 제공한다고 가정합니다. 이 가정은 Mono가 네임스페이스의 구현을 가지고 있지만 위의 "세 가지 오류 계층에 대한 세부 정보"의 #2 및 #3에서 설명한 대로 현재 구현이 불완전하다는 점에서 "정확"합니다. 따라서 Mono 팀이 버그 27337 및 버그 34890을 해결하는 것이 적절한 수정 사항입니다.

다음 단계

추가 지원이 필요하면 Microsoft에 문의하고, 위의 정보를 참조한 후에도 이 문제가 계속 발생하는 경우 Xamarin에 사용할 수 있는 지원 옵션은 무엇인가요?에서 문의 옵션, 제안 사항 및 필요한 경우 새 버그를 보고하는 방법에 대한 정보를 참조하세요.