Практический пример PCL. Как устранять проблемы, связанные с System.Diagnostics.Tracing для пакета NuGet потока данных библиотеки параллельных задач Майкрософт

Внимание

Этот конкретный System.Diagnostic.Tracing пример больше не создает никаких ошибок по умолчанию в последних версиях Xamarin. Хотя предлагаемое решение по-прежнему будет работать, обратите внимание, что некоторые ошибки, упоминание в разделе "Слои ошибок", были исправлены. Кроме того, следует отметить, что .NET Standard теперь является предпочтительным способом реализации кроссплатформенных API .NET.

Итоги

Xamarin.iOS и Xamarin.Android не реализуют все профили PCL, которые они могут использовать в качестве ссылок, на 100 %. Для практического удобства в Visual Studio для Mac, Visual Studio и диспетчере пакетов NuGet проекты Xamarin позволяют использовать несколько профилей, которые имеют только неполные реализации. Например, ни Xamarin.iOS, ни Xamarin.Android в настоящее время не включают полную реализацию типов в пространстве имен PCL System.Diagnostics. Это ограничение приводит к трем уровням ошибок при попытке использовать версию пакета NuGet потока данных Microsoft TPL по умолчанию portable-net45+win8+wpa81 .

Обходное решение. Переключите проект приложения, чтобы ссылаться на portable-net45+win8+wp8+wpa81 версию библиотеки потоков данных TPL

(Это позволяет избежать всех трех уровней ошибок и работает для всех последних версий 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+wp8+wpa81 Изменение portable-net45+win8+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 библиотеки может не включать 100 % функциональных возможностей portable-net45+win8+wpa81 версии.

  • Диспетчер пакетов NuGet устанавливает portable-net45+win8+wpa81 версию пакета NuGet PCL по умолчанию, поэтому необходимо настроить ссылку вручную.

Сведения о трех уровнях ошибок

  1. Сборка фасада System.Diagnostics.Tracing.dll в настоящее время отсутствует во всех версиях Mac Xamarin.Android (недоступная ошибка 348888) и отсутствует во всех версиях Xamarin.iOS ниже 9.0 (или ниже XamarinVS 3.11.1443 в Windows) (исправлена ошибка 32388). Эта проблема приведет к одной из следующих ошибок в зависимости от параметров целевого объекта развертывания и компоновщика:

    • Xamarin.Android.Common.targets: ошибка: исключение при загрузке сборок: System.IO.FileNotFoundException: не удалось загрузить сборку System.Diagnostics.Tracing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f1d50a3a. Возможно, он не существует в профиле Mono для Android?

    • Не удалось загрузить файл или сборку System.Diagnostics.Tracing или одну из зависимостей. Системе не удается найти указанный файл. (System.IO.FileNotFoundException)

    • MTOUCH: ошибка MT3001: не удалось AOT сборку "/Users/macuser/Projects/TPLDataflow/UnifiedSingleViewIphone1/obj/i Телефон/Debug/mtouch-cache/64/Build/System.Threading.Tasks.Dataflow.dll'

    • MTOUCH: ошибка MT2002: не удалось устранить сборку: "System.Diagnostics.Tracing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a"

  2. Текущая реализация Mono типов в System.Diagnostics. Трассировка отсутствует некоторые перегрузки методов. Эта проблема приведет к одной из следующих ошибок компоновщика при создании приложения Xamarin:

    • /Library/Frameworks/Mono.framework/External/xbuild/Xamarin/Android/Xamarin.Android.Common.targets: erroring task LinkAssemblies: error XA2006: Reference to metadata item 'System.Void System.Diagnostics.Tracing.EventSource::WriteEvent(System.Int32,System.Object[])" (определено в System.Threading.Tasks.Dataflow, Version=4.5.24.0, Culture=neutral, PublicKeyToken=b03f5f7f1d50a3a') из "System.Threading.Tasks.Dataflow, Version=4.5.24.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a' не удалось устранить.

    • MTOUCH: ошибка MT2002: не удалось устранить ссылку "System.Void System.Diagnostics.Tracing.EventSource::WriteEvent(System.Int32,System.Object[])" из ссылки "System.Diagnostics.Tracing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f1d50a3a"

  3. Текущая реализация Mono типов в System.Diagnostics.Tracing также является пустой реализацией "фиктивный" (ошибка 34890). Поэтому любая попытка использовать эти методы во время выполнения может привести к непредвиденным результатам. В конкретном случае библиотеки потоков данных Microsoft TPL, кажется, что вызовы WriteEvent(System.Int32,System.Object[]) не являются важными для большинства действий библиотеки, поэтому исправление для "уровня 2" (ошибка 27337, добавление пустых реализаций), скорее всего, будет достаточно для большинства вариантов использования потока данных Microsoft TPL.

Вопросы и ответы

Я смог оставить связывание включено с portable-net45+win8+wpa81 версией библиотеки в старых версиях Xamarin.iOS или на Xamarin.Android. Как это работало?

Ответ

Можно получить сборку для успешного завершения сборки (с включенным связыванием) в более ранних версиях Xamarin.iOS или Xamarin.Android на Mac, если вы включаете ссылку наSystem.Diagnostics.Tracing.dll эталонную сборку [1], а не сборку фасада [2], но, к сожалению, это не является правильным решением. Эталонные сборки предназначены только для использования при создании переносимых библиотек, а не кода для конкретной платформы, например приложений. Попытка запустить код, содержащийся в эталонных сборках (а не только сборка) может привести к непредвиденным результатам. Правильное исправление будет для команды Mono, чтобы добавить недостающую WriteEvent(System.Int32,System.Object[]) перегрузку в EventSource тип (ошибка 27337). Теперь лучше всего переключиться на portable-net45+win8+wp8+wpa81 версию библиотеки потоков данных Microsoft TPL, как описано в разделе обходного решения выше.

(Для тех, кто может читать эту статью после просмотра связанного более краткого ответа из 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 или любой последней версии Xamarin.Android в Windows это решение является строго избыточным и может привести к ошибкам компиляции, аналогичной сборке System.Diagnostics.Tracing с тем же удостоверением.

  • Для Xamarin.iOS 8.10 или более поздней версии или для Xamarin.Android на Mac это решение поможет, но только для проблемы с отсутствием сборки уровня 1. Он не решит ошибки компоновщика уровня 2, поэтому это не полное решение.

Можно ли использовать пакет NuGet System.Diagnostics.Tracing для решения этой проблемы?

Ответ

Нет, пакет 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.

Next Steps

Чтобы получить дополнительную помощь, связаться с нами или если проблема остается даже после использования указанных выше сведений, сведения о способах связи, предложениях, а также о том, как при необходимости сообщить о новой ошибке, см. здесь.