试图从TFS工作区停止应用程序检索文件

Kal*_*exx 5 c# tfs tfs-sdk tfs2010

所以我试图从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();
Run Code Online (Sandbox Code Playgroud)

会发生什么事情,每次我运行这个应用程序(在多台机器上),它都会停止运行items[x].DownloadFile().TFS中的所有文件都没有锁定,一切都很好.尝试使用该Workspace.Get()方法会产生同样的结果.

如果我点击暂停,x将是一个特定值,但我无法访问items集合,因为当我这样做时,我得到"无法计算表达式,因为当前线程处于休眠状态,等待或加入".当我评估调用堆栈时,我得到:

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

我不知道该做些什么.每当我暂停应用程序时,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
Run Code Online (Sandbox Code Playgroud)

在该条目之后:

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
Run Code Online (Sandbox Code Playgroud)

之后,日志文件没有进一步的更新,我的应用程序停止了.我很困惑的是

1)当我指定一个完全不同的TFS工作区时,为什么这会尝试从TFS中提取应用程序代码

2)为什么在尝试检索文件后停止?它可能是因为它fmMain.cs是在Visual Studio中打开的,但它仍然应该例外,并且不会挂起.我可以通过visual studio正常打开文件时获取最新信息.



EDIT2:

好的,所以我通过MSDN阅读,我注意到工作区名称可以是文件的本地路径.所以我将我传入的workspaceName参数作为参数修改为文件的本地目录.我仍然得到档位,但日志文件不清楚原因.我在这里上传了tf.log文件(我显然已经更改了专有信息,例如服务器和项目名称,但其他一切都没有改动).在最后一个日志条目之后,没有其他数据写入日志.

Rob*_*cus 7

GetItems不使用工作空间名称,它采用服务器路径来获取文件列表.如果你想从特定区域获取文件的副本,你想要做的是:

  var items = sourceControl.GetItems("$/Project/Path/subpath"/et cetera", VersionSpec.Latest, RecursionType.Full)
                                 .Items
                                 .Where(x => x.ItemType == ItemType.File)
                                 .ToList();
Run Code Online (Sandbox Code Playgroud)

你打电话的时候

items[x].DownloadFile();
Run Code Online (Sandbox Code Playgroud)

它会返回一个流,而不是实际将文件下载到磁盘.如果你想在那时将文件写入磁盘,你需要做普通的流处理工作来写出来.

如果您实际上是想将文件从TFS导入工作区,那就有点不同了.

        VersionControlServer sourceControl = coll.GetService<VersionControlServer>();

        var ws = sourceControl.QueryWorkspaces(workspaceName, null, null);

        var status = ws[0].Get();
Run Code Online (Sandbox Code Playgroud)

(错误处理需要添加到此)

这将使用服务器中的文件刷新工作区.它将像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);
Run Code Online (Sandbox Code Playgroud)