0

I am making a new ASP.NET Core 2.0 project, essentially a Web API. I have to reference several assemblies that are .NET 3.5 assemblies, so I am running this as a .NET Framework project, just using the .NET Core improvements where possible.

The referenced .NET framework 3.5 assembly references TaskParallelLibrary (1.0.2856). And I think that's where my issues are coming in. It's worth noting the Web API worked on its sample endpoints and all worked as expected.

When I run the application and try and use the referenced library, the call fails and I receive the following exception:

Could not load file or assembly 'System.Threading, Version=1.0.2856.102, Culture=neutral,
PublicKeyToken=31bf3856ad364e35'    
or one of its dependencies. The system cannot find the file specified.

I have tried several things, including:

Adding an App.configx file to try and force it to target .NET framework 4's System.Threading, on the assumption that that will be available. Inspired by a page I can't find the link for:

Here's the content:

<?xml version="1.0" encoding="utf-8"?>
<configuration>
    <!-- this is only here for binding redirects -->
  <runtime>
    <assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
      <dependentAssembly>
        <assemblyIdentity name="System.Threading" publicKeyToken="31bf3856ad364e35" culture="neutral" />
        <bindingRedirect oldVersion="0.0.0.0-4.0.0.0" newVersion="4.0.0.0" />
      </dependentAssembly>      
    </assemblyBinding>
  </runtime>
</configuration>

Directly adding the TaskTPLLibrary package at that version to the project. So far, it hasn't helped.

Adding the Microsoft.Bcl.Async library to my project. Again, nothing.

Trying to directly import System.Threading from "C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework.NETCore\v4.5\System.Threading.dll". I get an error stating "The reference is invalid or unsupported."

I've tried several other things, including re-cloning, cleaning, re-cleaning, swearing vociferously and coming back at it another day, all to no avail.

My reading list includes (on this computer):

And probably others that I can't remember

Some additional information as this issue continues:

  • Creating a .NET Framework ASP.NET MVC app using .NET Framework 4.6.2 with the same underlying library does work. It does it indirectly using an intermediary .NET Framework 3.5 one (just for convenience as much as anything else).
  • A .NET Framework 4.6.2 Console App that uses the library directly also runs into this problem. So it seems not to be ASP.NET Core itself. I'll change the tags accordingly.
  • Making the 4.6.2 console use the intermediary 3.5 library doesn't resolve the issue.

Any help in resolving this issue much appreciated.

Craig Brett
  • 2,295
  • 1
  • 22
  • 27
  • Where did `TaskParallelLibrary` come from? It's not a BCL library. `System.Threading` is a core built-in library. You don't need to reference it. The Most TPL classes are core classes themselves too. Looks like the project references a custom dll with the unfortunate name `TaskParallelLibrary` – Panagiotis Kanavos Jul 03 '18 at 15:41
  • BTW .NET 3.5 had no Task support. Anything that mentioned Tasks for 3.5 was a third-party library that just looked like TPL. `Microsoft.Bcl.Async` was only meant as a stop-gap that provided `async/await` to .NET 4.0 applications, nothing more. – Panagiotis Kanavos Jul 03 '18 at 15:45
  • The TPL in the third party library was referenced by them I think to give them async/await support in .NET framework 3.5, I'm guessing. Looking at NuGet, Microsoft Corporation is the author of that package. I think it's meant in a similar way to Microsoft.Bcl.Async, based on what you're saying, just to sort of backport this over for people still stuck on older frameworks. Do you think it could be a naming conflict? – Craig Brett Jul 04 '18 at 08:49
  • @CraigBett that isn't the TPL. It's an abandoned package that was created to create *some* types that *looked like* the upcoming TPL for .NET 3.5. It was abandoned in 2012. Its classes *aren't* compatible with the TPL classes that came in .NET 4.0. Microsoft.Bcl.Async was created to provide *async* features on top of *.NET 4.0 only* during the migration to .NET 4.5 and native async/await. It *doesn't* work with the `TaskParallelLibrary` package. `Microsoft.Bcl.Async` itself was abandoned in 2014 because 4.0 is no longer supported. The earliest supported .NET version is 4.5.2 – Panagiotis Kanavos Jul 04 '18 at 09:06
  • Long story short, the classes in `TaskParallelLibrary` aren't compatible with .NET 4.0 and later, much less .NET Core. Thankfully, it wasn't used in any NuGet packages (it was a stopgap after all). If you want to migrate to .NET Core you'll have to remove that library from any project that uses it, fix any incompatibility errors (.NET 3.5 was actually 2.0 plus libraries, while 4.0 was a new runtime) and recompile. – Panagiotis Kanavos Jul 04 '18 at 09:08
  • If, on the other hand, you only got the binaries from a contractor without the source... oops. You should probably deploy the `TaskParallelLibrary` dlls as well but there's no guarantee they can be loaded. Binding redirection to `System.Threading.Task` won't work because those *aren't* the same assemblies and types. You may not be able to load it at all - 4.0 could load 2.0 assemblies, Core can load 4.0 assemblies but I don't know if Core can load 2.0 assemblies. If that works, you'll end up with two different sets of incompatible Task-related classes – Panagiotis Kanavos Jul 04 '18 at 09:16
  • @PanagiotisKanavos: This library is an internal one. Thankfully, I have the source, but the .NET 3.5 support for this library is a hard requirement, sadly. So if I'm understanding what you're saying correctly, I'm going to have to multi-target this package (and all other 3.5 ones) to target 3.5 and Standard, to keep everyone happy, am I right? And then remove the fake TPL from this library and find some alternative for .NET 3.5. I figured running it as .NET framework just using the .NET Core system (which ASP.NET lets you do) would be enough to get around this, but it seems not. – Craig Brett Jul 04 '18 at 11:40
  • As an interesting aside, using these libraries in a .NET Framework 4.6.2 standard ASP.NET Web API does work. So it seems to be a .NET Core thing. That might be the way I have to go around this until I can get permission to spend the time multi-targetting the client libraries. Sad times – Craig Brett Jul 04 '18 at 11:43
  • It's not a Core thing - the library is 6 years out of date and targets the *wrong* runtime. The time to migrate away from it was 2012. You don't need multitargeting either, just complete removal. The TPL types in .NET 4.0 work in Core as well. – Panagiotis Kanavos Jul 04 '18 at 11:48
  • Even in ASP.NET Core 4.6.2 you *won't* be able to use the incompatible types for asynchronous actions. `await` won't work with them. If it does, (if they implement a `GetAwaiter()` method) they won't use the same threadpool as the rest of the code. – Panagiotis Kanavos Jul 04 '18 at 11:49
  • @PanagiotisKanavos: It working on ASP.NET non-Core Framework 4.6 indicates that it is at least somehow to do with ASP.NET Core. I understand that .NET framework has newer shinier versions. However, as these libraries are used in desktop applications that are consumed by clients, "complete removal" is only an option if there is a replacement. Call it a client constraint. – Craig Brett Jul 04 '18 at 14:17
  • It's not working in 4.6.2 either. Try awaiting one of those "tasks" in an asynchronous action. What are you going to do anyway? Keep using the incompatible libraries until you find out that they interfer even with ASP.NET 4.6.2 ? – Panagiotis Kanavos Jul 04 '18 at 17:18
  • If you don't believe the compiler warnings, check the [TaskParallelLibrary](https://www.nuget.org/packages/taskparallellibrary) downloads - not even 200K. Then check the *correct* package, [System.Threading.Tasks](https://www.nuget.org/packages/System.Threading.Tasks/). 35 Million downloads. Nobody is using that old package – Panagiotis Kanavos Jul 04 '18 at 17:25
  • Await works fine as far as I can see. I can't use the official package and still use .NET 3.5. What you're suggesting will not work – Craig Brett Jul 05 '18 at 08:03
  • You did see that the owner of the package isn't Microsoft but a *Google Engineer* ? Check [his Github profile](https://github.com/OmerMor) since he's probably the only one that could really help you - he may have the old source somewhere – Panagiotis Kanavos Jul 05 '18 at 08:19
  • The same guy created TaskParallelLibrary but abandoned it. He also created [AsyncBridge](https://github.com/OmerMor/AsyncBridge/tree/master/src/AsyncBridge) which he still maintains – Panagiotis Kanavos Jul 05 '18 at 08:26
  • The "owner" in the NuSpec is actually Microsoft Corporation, feel free to check. The owner on NuGet just means the person that submitted it to NuGet, if this is what you mean: https://www.nuget.org/packages/TaskParallelLibrary/. – Craig Brett Jul 05 '18 at 10:48
  • In either case, it makes no difference, your essentially saying rewrite the underlying libraries in a higher .NET Framework and maintain them separately to the .NET 3.5 ones, or bust, which is something I'll never get support to do, so ASP.NET Core will not be used here unless there's another solution – Craig Brett Jul 05 '18 at 10:50

1 Answers1

0

As there's no reasonable answer forthcoming, I'm assuming that having a .NET 3.5 Framework library referenced that uses the TaskParallelLibrary will in essence mean that using any .NET above 4 will cause this error. Under unspecified conditions. Most of the time.

The only solution to this seems to be rewrite everything to multi-target .NET 3.5 and .NET Standard and have the Standard implementation use the real TPL and have the 3.5 one use the NuGet package.

Craig Brett
  • 2,295
  • 1
  • 22
  • 27