PCL case study: How can I resolve problems related to System.Diagnostics.Tracing for the Microsoft TPL Dataflow NuGet package?
- PDF for offline use:
Let us know how you feel about this.
Xamarin.iOS and Xamarin.Android do not implement 100% of every PCL profile that they allow as references. For practical convenience in Xamarin Studio, Visual Studio, and the NuGet package manager, Xamarin projects allow the use of several profiles that only have incomplete implementations. For example, neither Xamarin.iOS nor Xamarin.Android currently includes a complete implementation of the types in the "System.Diagnostics.Tracing" PCL namespace. This limitation leads to 3 layers of errors when trying to use the default
portable-net45+win8+wpa81 version of the Microsoft TPL Dataflow NuGet package.
Workaround: Switch the app project to reference the
portable-net45+win8+wp8+wpa81 version of the TPL Dataflow library
(This avoids all 3 layers of errors and works for all recent versions of Xamarin.)
Open the application project
.csprojfile in a text editor.
Find the line that looks similar to this:
portable-net45+win8+wp8+wpa81 version of the library does not reference "System.Diagnostics.Tracing.dll" at all, so it completely avoids all 3 layers of problems.
portable-net45+win8+wp8+wpa81version of the library might not include 100% of the functionality of the
The NuGet package manager installs the
portable-net45+win8+wpa81version of the PCL NuGet package by default, so you must adjust the reference by hand.
Details about the 3 layers of errors
System.Diagnostics.Tracing.dllfacade assembly is currently absent from all Mac versions of Xamarin.Android (non-public Bug 34888) and absent from all Xamarin.iOS versions lower than 9.0 (or lower than XamarinVS 3.11.1443 on Windows) (fixed in Bug 32388). This problem will cause one of the following errors depending on deployment target and linker settings:
Xamarin.Android.Common.targets: Error: Exception while loading assemblies: System.IO.FileNotFoundException: Could not load assembly 'System.Diagnostics.Tracing, Version=18.104.22.168, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a'. Perhaps it doesn't exist in the Mono for Android profile?
Could not load file or assembly 'System.Diagnostics.Tracing' or one of its dependencies. The system cannot find the file specified. (System.IO.FileNotFoundException)
MTOUCH: error MT3001: Could not AOT the assembly '/Users/macuser/Projects/TPLDataflow/UnifiedSingleViewIphone1/obj/iPhone/Debug/mtouch-cache/64/Build/System.Threading.Tasks.Dataflow.dll'
MTOUCH: error MT2002: Failed to resolve assembly: 'System.Diagnostics.Tracing, Version=22.214.171.124, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a'
The current Mono implementation of the types in "System.Diagnostics.Tracing" is missing some method overloads (Bug 27337). This problem will cause one of the following linker errors when building a Xamarin app:
/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=126.96.36.199, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a') from 'System.Threading.Tasks.Dataflow, Version=188.8.131.52, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a' could not be resolved.
MTOUCH: error MT2002: Failed to resolve "System.Void System.Diagnostics.Tracing.EventSource::WriteEvent(System.Int32,System.Object)" reference from "System.Diagnostics.Tracing, Version=184.108.40.206, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a"
The current Mono implementation of the types in "System.Diagnostics.Tracing" is also currently an empty "dummy" implementation (Bug 34890). Any attempt to use these methods at run time might therefore produce unexpected results. For the particular case of the Microsoft TPL Dataflow Library, it seems the calls to
WriteEvent(System.Int32,System.Object)are not essential for most of the library's behavior, so the fix for "layer 2" (Bug 27337, adding empty implementations) will likey be sufficient for most Microsoft TPL Dataflow use cases.
Questions & Answers
"I was able to leave linking enabled with the
portable-net45+win8+wpa81 version of the library on older versions of Xamarin.iOS or on Xamarin.Android. How did that work?"
It is possible to get the build to complete "successfully" (with linking enabled) in older versions of Xamarin.iOS or in Xamarin.Android on Mac if you include a reference to the
System.Diagnostics.Tracing.dll reference assembly  rather than the facade assembly , but unfortunately this is not a "correct" workaround. Reference assemblies are only meant to be used when building portable libraries, not platform-specific code like apps. Attempting to run the code contained in reference assemblies (rather than just build against it) is likely to produce unexpected results. The correct fix will be for the Mono team to add the missing
WriteEvent(System.Int32,System.Object) overload to the
EventSource type (Bug 27337). For now the best option is to switch to the
portable-net45+win8+wp8+wpa81 version of the Microsoft TPL Dataflow library as discussed in the Workaround section above.
(For anyone who might be reading this article after seeing a related older, briefer answer from StackOverflow (http://stackoverflow.com/a/23591322/2561894), note that the distinction between reference assemblies and facade assembly was not mentioned there.)
 "Reference assembly" locations
C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETPortable\v4.5\System.Diagnostics.Tracing.dll
 "Facade assembly" locations
C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework.NETFramework\v4.5\<strong>Facades</strong>\System.Diagnostics.Tracing.dll
"Will it help if I manually add a reference to the "System.Diagnostics.Tracing" facade assembly?"
In particular can I solve the problem using these 2 steps?
System.Diagnostics.Tracing.dllfacade assembly into the application project folder from one of the following locations:
C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.5\Facades\System.Diagnostics.Tracing.dll
Add a reference to the facade assembly in the Xamarin.iOS or Xamarin.Android application project.
No, this will not help.
For Xamarin.iOS 9.0 or any recent version of Xamarin.Android on Windows, this workaround is strictly redundant, and might cause compile errors similar to "An assembly `System.Diagnostics.Tracing' with the same identity has already been imported.".
For Xamarin.iOS 8.10 or lower or for Xamarin.Android on Mac, this workaround will help but only for the "layer 1" missing assembly problem. It will not solve the "layer 2" linker errors, so it is not a complete solution.
"Can I use the System.Diagnostics.Tracing NuGet package to solve the problem?"
No, the NuGet 3.0 "System.Diagnostics.Tracing" package only includes platform-specific implementations for "DNXCore50" and "netcore50". It explicitly omits implementations for Xamarin.Android ("MonoAndroid") and Xamarin.iOS ("MonoTouch" and "xamarinios"). This means that installing the package will have no effect for Xamarin.Android and Xamarin.iOS projects. The NuGet package assumes that both of those platforms provide their own implementation of the types. This assumption is "correct" in the sense that Mono does have an implementation of the namespace, but as discussed under points #2 and #3 of "Details about the 3 layers of errors" above, the implementation is currently incomplete. So the proper fix will be for the Mono team to resolve Bug 27337 and Bug 34890.
For further assistance, to contact us, or if this issue remains even after utilizing the above information, please see What support options are available for Xamarin? for information on contact options, suggestions, as well as how to file a new bug if needed.