VS 2012 RC中TPL Dataflow和TPL引用的问题

16

我刚刚将Visual Studio 11 Beta升级到了新的Visual Studio 2012 RC版本,之后在引用TPL Dataflow时遇到了问题。

首先,我尝试像以前一样从框架中添加引用Dataflow。但是当我尝试这样做时,会出现一个错误提示框:

无法添加对 'System.Threading.Tasks.Dataflow' 的引用。

然后整个Visual Studio就会冻结。

在阅读了MEF和TPL Dataflow NuGet包适用于.NET Framework 4.5 RC之后,我认为显示在引用列表中的Dataflow版本是先前安装的某种工件。所以我尝试使用NuGet中的Dataflow,这似乎有效,直到我实际尝试编译我的代码,因为我得到了一个错误:

类型'System.Threading.Tasks.Task'在未被引用的程序集中定义。您必须添加对程序集'System.Threading.Tasks, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a'的引用。

这很令人困惑,因为Task在mscorlib中,不需要其他引用。但是引用列表中有一个名为System.Threading.Tasks的引用程序集,所以我尝试添加它。不幸的是,出现了一个熟悉的错误:

无法添加对'System.Threading.Tasks'的引用。

然后Visual Studio再次冻结了。

我做错了什么吗?如何在VS 2012 RC中使用TPL Dataflow?


这是一个新项目还是现有项目? - James Manning
问题发生在创建新项目时。打开使用了 TPL Dataflow 的 VS11 Beta 创建的项目是正常的。 - svick
我已经在Connect上发布了这个bug。 - svick
@svick:其他人无法访问您的错误报告。 - Oleg
@Oleg 你说得对,抱歉,我没有注意到。现在应该已经修复了。 - svick
有趣的是:修复安装后,STTD和STT从引用列表中删除了,但NuGet TPL Dataflow仍然需要它们。 - svick
2个回答

25
尝试明确地从'C:\ Program Files(x86)\ Reference Assemblies \ Microsoft \ Framework \ .NETCore \ v4.5'添加'System.Threading.Tasks.dll'的“添加引用”。或者,您可以使用'C:\ Program Files(x86)\ Reference Assemblies \ Microsoft \ Framework \ .NETFramework \ v4.5 \ Facades'目录。更新后,我在阅读有关删除对'System.Runtime'引用的答案后更详细地研究了该问题并可以添加以下内容:由于NuGet软件包'Microsoft.Tpl.Dataflow.4.5.1-rc'当前版本中的错误,将添加对'System.Runtime'的引用。如果在Visual Studio中直接添加对相同的'System.Threading.Tasks.Dataflow.dll'的引用,则不会添加'System.Runtime'引用,也不存在任何问题。
使用NuGet Package Explorer,可以从“NuGet官方软件包源”下载原始的Microsoft.Tpl.Dataflow.4.5.1-rc.nupkg。在软件包元数据的末尾,您将看到

enter image description here

您可以修改元数据(按下Ctrl-K),并删除引用:

enter image description here

接下来,您可以将修改后的文件Microsoft.Tpl.Dataflow.4.5.1-rc.nupkg保存到某个目录中。在NuGet源列表中添加新位置(本地目录)之后(请参见此处此处),您将能够从本地源添加新软件包(不要忘记选择显示所有软件包包括预发布版本,请参见下面的图片):

enter image description here

修改后的 Microsoft.Tpl.Dataflow.4.5.1-rc.nupkg 将不会添加 System.Runtime,项目将编译无误。
因此,这个问题并不在于 Visual Studio 2012 RC,甚至不在于 Microsoft.Tpl.Dataflow.dll。问题只存在于当前可用于“NuGet官方软件源”的预发布版本 Microsoft.Tpl.Dataflow NuGet包的元数据中。
您可以向autors提交错误报告,以便修复该软件包。
更新2:即使我的答案已被标记为已解决并获得了悬赏,问题仍然存在于我的头脑中。实际上,我看到两个未解决的问题:
1.为什么存在未使用的程序集 System.Runtime 会在构建项目时产生错误。 2.我注意到NuGet软件包的卸载或更新方式存在一些一般性问题(详见后文)。
让我们先接受第一个问题是独立于原因存在的事实。第二个问题让我感到不安。我看到了真正的问题所在。每个人都可以进行以下实验,以更好地理解我:
  1. 在Visual Studio 2012 RC中创建一个新的空控制台应用程序。
  2. 验证项目没有引用 System.Runtime
  3. 从 "工具" / "库包管理器" 中打开 "程序包管理器控制台"。
  4. 在 "程序包管理器控制台" 中执行命令 "Install-Package Microsoft.Tpl.Dataflow -Pre"。
  5. 验证项目的引用列表中包含了 System.RuntimeSystem.Threading.Tasks.Dataflow
  6. 在 "程序包管理器控制台" 中执行命令 "Uninstall-Package Microsoft.Tpl.Dataflow"。
  7. 验证 System.Threading.Tasks.Dataflow 已从项目的引用列表中删除,但 System.Runtime 仍在引用列表中

我进行了另一次实验,将修改后的Microsoft.Tpl.Dataflow.4.5.1-rc.nupkg版本更改为本地保存的4.5.1-rc1版本,并删除了对System.Runtime的引用。此后,我可以在我的项目更新列表中看到“新”的版本:

enter image description here

如果我安装更新,对于System.Runtime的引用也不会被删除。因此,NuGet的"更新"和"卸载"当前实现存在缺陷或一般性设计问题。如果我们将一个包添加到我们的项目中并对该项目进行一些更新,我们将获得所有旧版本的所有依赖程序集的引用。旧版本包由NuGet添加的旧引用在卸载或更新期间不会被删除。首先,在项目引用中存在垃圾本身就不好,但是由于存在第一个问题(如果未引用的System.Runtime引用存在,则编译时出错),问题甚至会更加严重。

因此,如果NuGet中没有任何更改,那么更新到下一个版本的Microsoft.Tpl.Dataflow将无法解决已安装Microsoft.Tpl.Dataflow 4.5.1(或可能早期版本)的用户的问题。所有用户都必须手动删除对System.Runtime的引用。我认为这是真正的NuGet问题,必须由NuGet开发人员解决。我稍后将在http://nuget.org/上发布该问题的描述。

我提交给NuGet的错误报告可以在这里找到(抱歉文本格式不完美)。


谢谢,看起来这个方法可行(我使用了第二种)。你知道为什么会发生这种情况吗? - svick
@svick:我没有详细检查过这个问题。在没有参考的情况下,新版本的System.Threading.Tasks.Dataflow尝试使用错误版本的System.Threading.Tasks.dll。我以前没有使用过TPL Dataflow。我只是从该页面复制了演示代码,并得到了您描述的错误以及workerBlock.Completion.Wait();行中的错误:Wait方法不存在。很明显,Microsoft更改了一些类,而我使用了错误的程序集。因此,只需要找到正确的程序集即可。 - Oleg
顺便说一下,我在博客的结尾找到了一个提示,建议添加与我在答案中描述的相同引用。因此,似乎你不是第一个遇到这个问题的人。 - Oleg
步骤“添加对System.Threading.Tasks.dll的引用”帮助我解决了类似问题: 在我的项目中引用的可移植类库(PCL)中,.Net 4.6 Roslyn编译器无法识别Task<>返回。 - digiogo
@digiogo:不客气!我很高兴知道旧答案仍然对某些情况有帮助。 - Oleg
显示剩余5条评论

2
根据来自微软的Alok Shriram的说法,解决方案是移除对System.Runtime的引用,并且这将在下一个版本中修复。我可以确认,实际上删除该引用会解决这个问题。

从项目中删除对System.Runtime.dll的引用比添加新的引用System.Threading.Tasks.dll更好。另一方面,它并没有真正清楚为什么存在冲突。我使用“IL Disassembler”(ildasm.exe)检查了System.Runtime.dll的清单,并没有看到任何冲突。所以对我来说,两种方法都是:“这样做问题就会解决”。所以我可以重复你最初问我的同样的问题:“有什么想法为什么会发生这种情况?” - Oleg
是的,我也想知道。SR 中不包含任何对 STT 的 AssemblyRef,所以我不知道为什么删除它会有帮助。 - svick
此外,对 System.Runtime 的引用是由执行 Install-Package Microsoft.Tpl.Dataflow -Pre 命令添加的,但是文件 system.threading.tasks.dataflow.xml 中没有包含任何 System.Runtime 文本。如果我们遇到一些程序集加载问题,可以使用 Fuslogvw.exe 进行跟踪,但我们现在遇到了编译器错误。顺便说一下,我使用了 ReSharper,它可以帮助删除未使用的引用,但是不像其他引用那样删除 System.Runtime - Oleg
顺便说一下,如果将两个引用都删除,然后手动添加.\packages\Microsoft.Tpl.Dataflow.4.5.1-rc\lib\net45\System.Threading.Tasks.Dataflow.dll第二个dll(System.Runtime.dll)将不会被添加。因此我认为原因可能更多地在于NuGet包。我使用NuGet Package Explorer进行了检查,但是在NuGet Package Explorer的GUI中无法直接看到对System.Runtime.dll的任何引用(至少我没有看到)。所以问题对我来说仍然不是完全清楚的。 - Oleg
哦,我不够仔细。NuGet包资源管理器确实显示Microsoft.Tpl.Dataflow需要System.Runtime.dll。在“框架程序集引用”下的包元数据中,可以看到“System.Runtime”。因此,问题起源的一部分至少是Microsoft.Tpl.Dataflow.4.5.1-rc.nupkg包含对错误的System.Runtime.dll的引用。 - Oleg
我们已经发布了4.5.4-rc版本的NuGet包来修复这个问题。 - Nicholas Blumhardt

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接