尝试从 TFS 工作区检索文件会导致应用程序停止运行

发布于 2024-10-16 13:17:37 字数 2280 浏览 2 评论 0原文

因此,我尝试从 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 始终处于相同的值(但对于每个运行的应用程序来说,它停止的值都不同)。

有人有什么想法吗?


Edit: After adding diagnostic logic (based on the link in Grant's answer) I am even more confused than ever.

我传递到此方法的工作空间是 $/QA/Automated Test Scripts/Regression 或 System Test Scripts/RDE 或 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 正常打开时,我可以获得最新版本。



Edit2:

好的,我正在阅读 MSDN,我注意到工作区名称可以是文件的本地路径。因此,我修改了作为 workspaceName 参数传递到文件的本地目录的内容。我仍然遇到停顿,但日志文件对于原因不太清楚。我已经上传了 tf.log 文件这里(我显然已经更改了专有信息,例如服务器和项目名称,但其他所有内容均保持不变)。在最后一个日志条目之后,不会再将任何数据写入日志。

So I am attempting to retrieve the files from a workspace in TFS. Unfortunately, every attempt that I have made to do this results in a stalled application. As of right now, this is the code:

    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();

What happens is that every time I run this application (on multiple machines) it stalls on items[x].DownloadFile(). All the files in TFS are not locked, everything is fine. Attempting to use the Workspace.Get() method results in the same thing.

If I hit pause, x will be a specific value, but I can't access the items collection, as when I do I get "Cannot evaluate expression because the current thread is in a sleep, wait, or join". When I evaluation the call stack I get:

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

I am at a loss at what to do further. Whenever I pause the application, x is always at the same value (the value that it stalls on is different for every application run though).

Anyone have any ideas?


Edit: After adding diagnostic logic (based on the link in Grant's answer) I am even more confused than ever.

The workspace I am passing into this method is $/QA/Automated Test Scripts/Regression or System Test Scripts/RDE or Condo (verified through the debugger).

However, when I look at the tfs logs, it looks to be downloading the code file that I am running, as it says:

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

Right after that entry is:

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

After that there are no further updates to the log file, and my application is stalled. What I am confused about is

1) Why is this trying to pull the application code from TFS when I am specifying a completely different TFS workspace

2) Why is this stalling after attempting to retrieve the file? It's possible that it's because fmMain.cs is open in Visual Studio, but it should still exception out and not get hung up. I'm able to get latest while the file is open via visual studio normally.



Edit2:

Ok so I was reading through MSDN and I noticed that the workspace name can be the local path to the files. So I modified what I passed in as the workspaceName parameter to the local directory of the files. I still get stalls, but the log file is a lot less clear on why. I have uploaded the tf.log file here (I have obviously changed proprietary information, such as server and project names, but everything else is untouched). After that last log entry, no further data is written to the log.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

演多会厌 2024-10-23 13:17:37

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 的映射,则只会获取该映射中的文件。

在我们的几个内部实用程序中,我们甚至采取了以下措施:

  • 动态创建工作区
  • 仅将路径映射到我们需要获取的路径的目录
  • 执行 get
  • 编辑某些文件(使用 PendEdit() 方法)
  • 检查在更改的文件中
  • 最后,删除工作区

如果您只是尝试自动刷新一组文件,那么这是一项繁重的工作,因此您可以做的是将路径传递给 Get()< /代码>方法:

var status = ws[0].Get(new GetRequest("$/path/to/subfolder", RecursionType.Full, VersionSpec.Latest),
                   GetOptions.Overwrite);

GetItems doesn't take a workspace name, it takes a server path to get a list of files. if you're trying to get a copy of files from a specific area, what you want to do is:

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

When you call

items[x].DownloadFile();

it is returning you a stream, not actually downloading the file to disk. If you want to write the file to disk at that point, you'll need to do normal stream handling stuff to write it out.

If you are actually trying to get files from TFS into a workspace, it's a little different.

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

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

        var status = ws[0].Get();

(Error handling needs added to this)

This will refresh your workspace with files from the server. It will work just like the Visual Studio UI, in that it will compare what's currently on disk with what is in the repository, and will update the local version if a newer version exists.

There are a number of overloads to the Get() method that you can use to specify the exact behavior you are looking for.

--Edit--

When you call Workspace.Get(), the first thing it does is go out to TFS (using a web service call) and gets a list of files. Then, it iterates through those files, comparing what you have already "gotten" in that workspace, to what is at the revision you requested (or VersionSpec.Latest if you didn't specify any other revision).

This process can take a while. It's just like right-clicking and getting latest on every mapped directory in your workspace.

If your workspace is mapped to $/, it's going to iterate through all files in TFS. If you have multiple mappings of paths to local paths, it will go through each one, and it will retrieve and save locally any files that you haven't already gotten.

Refreshing an entire workspace can take a very long time unless you are careful on what you have mapped.

-- EDIT 2 --

If you're looking to limit what you're getting, you have a couple options. The first option is to limit the mapping within the workspace that you are accessing. For example, if your workspace has only one mapping to $/Project/Branch/Source/Utilities/MyUtility, only the files in that mapping will be gotten.

In a couple of our in-house utilities, we even go so far as to:

  • Dynamically create a workspace
  • Map paths to directories for only those paths that we need to get
  • Do a get
  • Edit certain files (using the PendEdit() method)
  • Check in the changed files
  • And, finally, remove the workspace

This is a lot of work if you're just trying to automate refreshing a set of files, so what you can do is pass in a path to the Get() method:

var status = ws[0].Get(new GetRequest("$/path/to/subfolder", RecursionType.Full, VersionSpec.Latest),
                   GetOptions.Overwrite);
や三分注定 2024-10-23 13:17:37

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

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

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

Does the same command/parameters work when using the TFS command-line tools? e.g. TF.exe get ?

Do you have any anti-virus software installed? Is it possible that it's getting in the way? Try temporarily disabling it.

You can also enable TFS Client-Side tracing in your app.config to see what's going over the wire:
http://blogs.msdn.com/b/edhintz/archive/2007/03/30/tfs-client-tracing.aspx

风月客 2024-10-23 13:17:37

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

var status = workspace.Get(new GetRequest("$/XXXX/Development/Subfolder/",
            RecursionType.Full, VersionSpec.Latest),
            GetOptions.GetAll| GetOptions.Overwrite);

Following is the working example using which you can get the latest version of the code from server path

var status = workspace.Get(new GetRequest("$/XXXX/Development/Subfolder/",
            RecursionType.Full, VersionSpec.Latest),
            GetOptions.GetAll| GetOptions.Overwrite);
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文