所以我试图从 TFS 的工作区中检索文件。不幸的是,我为此所做的每一次尝试都会导致应用程序停滞。截至目前,这是代码:
public void GetWorkspaceFiles(string workspaceName)
{
VersionControlServer sourceControl = (VersionControlServer)TfsServer.GetService(typeof(VersionControlServer));
var items = sourceControl.GetItems(workspaceName, VersionSpec.Latest, RecursionType.Full)
.Items
.Where(x => x.ItemType == ItemType.File)
.ToList();
for (int x = 0; x < items.Count; x++)
items[x].DownloadFile();
每次我运行此应用程序(在多台机器上)时,它都会在 items[x].DownloadFile()
上停止。 TFS 中的所有文件都没有被锁定,一切正常。尝试使用 Workspace.Get()
方法会产生同样的结果。
如果我点击暂停,x 将是一个特定值,但我无法访问项目集合,因为当我这样做时我得到“无法计算表达式,因为当前线程处于 sleep 、等待或加入状态”。当我评估调用堆栈时,我得到:
[In a sleep, wait, or join]
[External Code]
GetWorkspaceFiles(string workspaceName) Line 55
我不知道该怎么做。每当我暂停应用程序时,x
始终处于相同的值(它停止的值对于每个运行的应用程序都是不同的)。
有人有什么想法吗?
编辑: 添加诊断逻辑(基于 Grant 回答中的链接)后,我比以往任何时候都更加困惑。
我传递给这个方法的工作区是$/QA/Automated Test Scripts/Regression or System Test Scripts/RDE or Condo
(通过调试器验证)。
但是,当我查看 tfs 日志时,它看起来正在下载我正在运行的代码文件,如它所说:
02/10/2011 12:26:58 (pid 5808, tid 5968, 42180 ms) Recording OperationStatus.Getting for $/QA/Automated Test Scripts/QA Tools/Test Manager/Test Polling Server/fmMain.cs
在该条目之后是:
02/10/2011 12:26:58 (pid 5808, tid 5968, 42180 ms) DownloadFiles: 18 ms
02/10/2011 12:26:58 (pid 5808, tid 5968, 42181 ms) Acknowledgements: 0 ms
此后日志文件没有进一步更新,我的应用程序停止了。我困惑的是
1) 当我指定一个完全不同的 TFS 工作区时,为什么要尝试从 TFS 中提取应用程序代码
2) 为什么在尝试检索文件后会停止?可能是因为 fmMain.cs
在 Visual Studio 中打开了,但它应该仍然会异常输出并且不会挂断。当文件正常通过 visual studio 打开时,我可以获得最新信息。
编辑2:
好的,我在阅读 MSDN 时注意到工作区名称可以是文件的本地路径。因此,我将作为 workspaceName
参数传入的内容修改为文件的本地目录。我仍然遇到停顿,但日志文件并不清楚原因。我已经上传了 tf.log 文件 here (我显然已经更改了专有信息,例如服务器和项目名称,但其他一切都没有改变)。在最后一个日志条目之后,没有进一步的数据写入日志。
最佳答案
GetItems 不采用工作区名称,它采用服务器路径来获取文件列表。如果您想从特定区域获取文件副本,您需要做的是:
var items = sourceControl.GetItems("$/Project/Path/subpath"/et cetera", VersionSpec.Latest, RecursionType.Full)
.Items
.Where(x => x.ItemType == ItemType.File)
.ToList();
当你打电话时
items[x].DownloadFile();
它向您返回一个流,而不是实际将文件下载到磁盘。如果您想在此时将文件写入磁盘,则需要进行正常的流处理才能将其写出。
如果您实际上是在尝试将文件从 TFS 获取到工作区,则情况有所不同。
VersionControlServer sourceControl = coll.GetService<VersionControlServer>();
var ws = sourceControl.QueryWorkspaces(workspaceName, null, null);
var status = ws[0].Get();
(需要添加错误处理)
这将使用来自服务器的文件刷新您的工作区。它将像 Visual Studio UI 一样工作,因为它将比较当前磁盘上的内容与存储库中的内容,如果存在更新版本,则会更新本地版本。
Get() 方法有许多重载,您可以使用它们来指定您正在寻找的确切行为。
--编辑--
当您调用 Workspace.Get() 时,它所做的第一件事是转到 TFS(使用 Web 服务调用)并获取文件列表。然后,它遍历这些文件,将您在该工作区中已经“获得”的内容与您请求的修订版本(或 VersionSpec.Latest,如果您未指定任何其他修订版本)进行比较。
此过程可能需要一段时间。这就像右键单击并获取工作区中每个映射目录的最新信息。
如果您的工作区映射到 $/
,它将遍历 TFS 中的所有文件。如果您有多个路径到本地路径的映射,它会遍历每个路径,并且会在本地检索并保存您尚未获得的任何文件。
刷新整个工作区可能会花费很长时间,除非您对映射的内容非常小心。
-- 编辑 2 --
如果您希望限制获得的数量,您有多种选择。第一个选项是限制您正在访问的工作区内的映射。例如,如果您的工作区只有一个到 $/Project/Branch/Source/Utilities/MyUtility
的映射,则只会获取该映射中的文件。
在我们的一些内部实用程序中,我们甚至做到了:
- 动态创建工作空间
- 仅为我们需要获取的那些路径将路径映射到目录
- 做一个获取
- 编辑某些文件(使用 PendEdit() 方法)
- checkin 更改的文件
- 最后,删除工作区
如果您只是尝试自动刷新一组文件,这将是一项繁重的工作,因此您可以将路径传递给 Get()
方法:
var status = ws[0].Get(new GetRequest("$/path/to/subfolder", RecursionType.Full, VersionSpec.Latest),
GetOptions.Overwrite);
关于c# - 尝试从 TFS 工作区检索文件会使应用程序停止,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4958113/