5

所以我试图从 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 将是一个特定值,但我无法访问项目集合,因为当我这样做时,我得到“无法评估表达式,因为当前线程处于睡眠、等待或加入状态”。当我评估调用堆栈时,我得到:

[In a sleep, wait, or join]
[External Code]
GetWorkspaceFiles(string workspaceName) Line 55

我不知道该怎么做。每当我暂停应用程序时,x它总是处于相同的值(尽管每个应用程序运行的值都不同)。

有人有想法么?


编辑:添加诊断逻辑(基于格兰特答案中的链接)后,我比以往任何时候都更加困惑。

我传递给此方法的工作区是$/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 文件(我显然更改了专有信息,例如服务器和项目名称,但其他所有内容都保持不变)。在最后一个日志条目之后,不再向日志写入数据。

4

3 回答 3

7

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() 方法)
  • 签入更改的文件
  • 最后,删除工作区

如果您只是想自动刷新一组文件,这需要做很多工作,所以您可以做的就是将路径传递给该Get()方法:

var status = ws[0].Get(new GetRequest("$/path/to/subfolder", RecursionType.Full, VersionSpec.Latest),
                   GetOptions.Overwrite);
于 2011-02-11T13:50:15.190 回答
2

使用 TFS 命令行工具时,相同的命令/参数是否有效?例如TF.exe get

您是否安装了任何防病毒软件?有没有可能会碍事?尝试暂时禁用它。

您还可以在 app.config 中启用 TFS 客户端跟踪,以查看网络上发生了什么:http: //blogs.msdn.com/b/edhintz/archive/2007/03/30/tfs-client-tracing。 aspx

于 2011-02-10T16:04:39.317 回答
0

以下是工作示例,您可以使用它从服务器路径获取最新版本的代码

var status = workspace.Get(new GetRequest("$/XXXX/Development/Subfolder/",
            RecursionType.Full, VersionSpec.Latest),
            GetOptions.GetAll| GetOptions.Overwrite);
于 2014-01-29T09:16:24.387 回答