Microsoft.Bcl.Async 包和现代 csproj

Microsoft.Bcl.Async package and modern csproj

我正在尝试创建一个针对两个框架的库,.net core 和 .net framework 4.0。
我将 Microsoft.Bcl.Async 引用到 .net 4.0,以便我可以使用异步-await 功能....但我在编译时出错。

.csproj :

<Project Sdk="Microsoft.NET.Sdk">

  <PropertyGroup>
    <TargetFrameworks>netcoreapp2.0;net40</TargetFrameworks>
  </PropertyGroup>

  <ItemGroup Condition=" '$(TargetFramework)' == 'net40' ">
    <PackageReference Include="Microsoft.Bcl.Async" Version="1.0.168" />
  </ItemGroup>

</Project>

Class1.cs :

using System;
using System.Threading.Tasks;

namespace ClassLibrary1
{
    public class Class1
    {
        public static async Task Test()
        {
#if NET40
            await TaskEx.Delay(2000);
#else
            await Task.Delay(2000);
#endif
            Console.WriteLine("Test done");
        }
    }
}

并构建输出(错误):

1>------ Build started: Project: ClassLibrary1, Configuration: Debug Any CPU ------
1>C:\Program Files (x86)\Microsoft Visual Studio17\Professional\MSBuild.0\Bin\Microsoft.Common.CurrentVersion.targets(2106,5): warning MSB3268: The primary reference "C:\Users\Demon\.nuget\packages\microsoft.bcl.async.0.168\lib\net40\Microsoft.Threading.Tasks.Extensions.dll" could not be resolved because it has an indirect dependency on the framework assembly "System.Threading.Tasks, Version=1.5.11.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" which could not be resolved in the currently targeted framework. ".NETFramework,Version=v4.0". To resolve this problem, either remove the reference "C:\Users\Demon\.nuget\packages\microsoft.bcl.async.0.168\lib\net40\Microsoft.Threading.Tasks.Extensions.dll" or retarget your application to a framework version which contains "System.Threading.Tasks, Version=1.5.11.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a".
1>C:\Program Files (x86)\Microsoft Visual Studio17\Professional\MSBuild.0\Bin\Microsoft.Common.CurrentVersion.targets(2106,5): warning MSB3268: The primary reference "C:\Users\Demon\.nuget\packages\microsoft.bcl.async.0.168\lib\net40\Microsoft.Threading.Tasks.dll" could not be resolved because it has an indirect dependency on the framework assembly "System.Threading.Tasks, Version=1.5.11.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" which could not be resolved in the currently targeted framework. ".NETFramework,Version=v4.0". To resolve this problem, either remove the reference "C:\Users\Demon\.nuget\packages\microsoft.bcl.async.0.168\lib\net40\Microsoft.Threading.Tasks.dll" or retarget your application to a framework version which contains "System.Threading.Tasks, Version=1.5.11.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a".
1>C:\Program Files (x86)\Microsoft Visual Studio17\Professional\MSBuild.0\Bin\Microsoft.Common.CurrentVersion.targets(2106,5): warning MSB3268: The primary reference "C:\Users\Demon\.nuget\packages\microsoft.bcl.async.0.168\lib\net40\Microsoft.Threading.Tasks.Extensions.dll" could not be resolved because it has an indirect dependency on the framework assembly "System.Runtime, Version=1.5.11.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" which could not be resolved in the currently targeted framework. ".NETFramework,Version=v4.0". To resolve this problem, either remove the reference "C:\Users\Demon\.nuget\packages\microsoft.bcl.async.0.168\lib\net40\Microsoft.Threading.Tasks.Extensions.dll" or retarget your application to a framework version which contains "System.Runtime, Version=1.5.11.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a".
1>C:\Program Files (x86)\Microsoft Visual Studio17\Professional\MSBuild.0\Bin\Microsoft.Common.CurrentVersion.targets(2106,5): warning MSB3268: The primary reference "C:\Users\Demon\.nuget\packages\microsoft.bcl.async.0.168\lib\net40\Microsoft.Threading.Tasks.dll" could not be resolved because it has an indirect dependency on the framework assembly "System.Runtime, Version=1.5.11.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" which could not be resolved in the currently targeted framework. ".NETFramework,Version=v4.0". To resolve this problem, either remove the reference "C:\Users\Demon\.nuget\packages\microsoft.bcl.async.0.168\lib\net40\Microsoft.Threading.Tasks.dll" or retarget your application to a framework version which contains "System.Runtime, Version=1.5.11.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a".
1>Class1.cs(11,19,11,25): error CS0103: The name 'TaskEx' does not exist in the current context
1>Done building project "ClassLibrary1.csproj" -- FAILED.
1>ClassLibrary1 -> C:\Users\Demon\Documents\Visual Studio 2017\Projects\ConsoleApp257\ClassLibrary1\bin\Debug\netcoreapp2.0\ClassLibrary1.dll
========== Build: 0 succeeded, 1 failed, 0 up-to-date, 0 skipped ==========

问题已解决,Here the solution

创建一个名为 app.net40.config 的文件并放入以下内容:

<?xml version ="1.0"?>
<configuration>
  <runtime>
    <assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
      <dependentAssembly>
        <assemblyIdentity name="System.IO" publicKeyToken="b03f5f7f11d50a3a" culture="neutral" />
        <bindingRedirect oldVersion="0.0.0.0-2.6.8.0" newVersion="2.6.8.0" />
      </dependentAssembly>
      <dependentAssembly>
        <assemblyIdentity name="System.Runtime" publicKeyToken="b03f5f7f11d50a3a" culture="neutral" />
        <bindingRedirect oldVersion="0.0.0.0-2.6.8.0" newVersion="2.6.8.0" />
      </dependentAssembly>
      <dependentAssembly>
        <assemblyIdentity name="System.Threading.Tasks" publicKeyToken="b03f5f7f11d50a3a" culture="neutral" />
        <bindingRedirect oldVersion="0.0.0.0-2.6.8.0" newVersion="2.6.8.0" />
      </dependentAssembly>
    </assemblyBinding>
  </runtime>
</configuration>

你的 csproj 应该是这样的:

<Project Sdk="Microsoft.NET.Sdk">

  <PropertyGroup>
    <TargetFrameworks>net40;netstandard1.4</TargetFrameworks>
    <AppConfig Condition="'$(TargetFramework)' == 'net40'">App.net40.config</AppConfig>
    <AutoUnifyAssemblyReferences  Condition="'$(TargetFramework)' == 'net40'">false</AutoUnifyAssemblyReferences>
  </PropertyGroup>

  <ItemGroup Condition=" '$(TargetFramework)' == 'net40' ">
    <PackageReference Include="Microsoft.Bcl.Async" Version="1.0.168" />
    <Reference Include="System" />
    <Reference Include="Microsoft.CSharp" />
  </ItemGroup>
</Project>

然后编译。