Практический пример 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.)
Откройте файл проекта приложения CSPROJ в текстовом редакторе.
Найдите строку, похожую на следующую:
<HintPath>..\packages\Microsoft.Tpl.Dataflow.4.5.24\lib\portable-net45+win8+wpa81\System.Threading.Tasks.Dataflow.dll</HintPath>
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 по умолчанию, поэтому необходимо настроить ссылку вручную.
Сведения о трех уровнях ошибок
Сборка фасада 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"
Текущая реализация 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"
Текущая реализация 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 шагов?
Скопируйте сборку
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
Добавьте ссылку на сборку фасада в проекте приложения 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
Чтобы получить дополнительную помощь, связаться с нами или если проблема остается даже после использования указанных выше сведений, сведения о способах связи, предложениях, а также о том, как при необходимости сообщить о новой ошибке, см. здесь.