2011-02-10 5 views
5

Так что я пытаюсь получить файлы из рабочей области в TFS. К сожалению, каждая попытка, которую я сделал для этого, приводит к заторможенному приложению. По состоянию на данный момент, это код:Попытка получить файлы из рабочего пространства 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: После добавления диагностической логики (на основе связи в ответ Гранта) Я даже более запутанной, чем когда-либо.

Рабочее пространство, в которое я перехожу, это $/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) Почему этот глохнет после попытки получить файл? Вполне возможно, что это связано с тем, что в Visual Studio открыто fmMain.cs, но оно все равно должно исключаться и не зависеть. Я могу получить последние, пока файл открыт с помощью визуальной студии.



Edit2:

Хорошо, так что я читал через MSDN и я заметил, что имя рабочего пространства может быть локальный путь к файлам. Поэтому я изменил то, что я передал в качестве параметра workspaceName в локальный каталог файлов. Я все еще получаю киоски, но файл журнала намного менее понятен по причине. Я загрузил файл tf.log here (я, очевидно, изменил проприетарную информацию, такую ​​как имена серверов и проектов, но все остальное не тронуто). После этой последней записи журнала в журнал не записываются дополнительные данные.

+0

Вы использовали wirehark для просмотра данных, идущих туда и обратно? Я думаю, что это в основном для человека. –

+0

Никогда не слышал об этом раньше. Я проверю это. – KallDrexx

ответ

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, поскольку он будет сравнивать то, что в настоящее время находится на диске, с тем, что находится в репозитории, и будет обновлять локальную версию, если существует более новая версия.

Существует ряд перегрузок метода Get(), который вы можете использовать для указания точного поведения, которое вы ищете.

--Edit--

При вызове Workspace.Get(), то первое, что он делает это пойти на TFS (с помощью вызова веб-службы) и получает список файлов. Затем он выполняет итерацию через эти файлы, сравнивая то, что вы уже «получили» в этой рабочей области, к тому, что находится в запрошенной ревизии (или VersionSpec.Latest, если вы не указали какую-либо другую ревизию).

Этот процесс может занять некоторое время. Это просто щелчок правой кнопкой мыши и получение последней информации о каждом сопоставленном каталоге в вашей рабочей области.

Если ваше рабочее пространство сопоставлено с $/, оно будет проходить через все файлы в TFS. Если у вас есть несколько сопоставлений путей к локальным путям, он будет проходить через каждый, и он будет извлекать и сохранять локально любые файлы, которые вы еще не получили.

Обновление всего рабочего пространства может занять очень долгое время, если вы не будете осторожны с тем, что вы сопоставили.

- EDIT 2 -

Если вы хотите, чтобы ограничить то, что вы получаете, у вас есть пара вариантов. Первый вариант - ограничить отображение в рабочей области, к которой вы обращаетесь. Например, если ваше рабочее пространство имеет только одно сопоставление с $/Project/Branch/Source/Utilities/MyUtility, будут получены только файлы в этом сопоставлении.

В паре наших собственных утилит, мы даже пойти так далеки, чтобы:

  • Динамически создать рабочее пространство
  • Карты пути к каталогам только для тех путей, которые мы должны получить
  • сделать получить
  • Редактировать определенные файлы (с помощью метода PendEdit())
  • Проверки в измененных файлах
  • И, наконец, удалить Рабочая область

Это много работы, если вы просто пытаетесь автоматизировать освежающий набор файлов, так что вы можете сделать, это пройти в пути к Get() методу:

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

Использование вашего второго примера (с правильной рабочей областью) по-прежнему вызывает полный прилавок приложения на 'workspace [0] .Get();' – KallDrexx

+0

См. Мое редактирование для более подробного объяснения. – Robaticus

+0

Есть ли специальный способ обновления определенных папок (рекурсивно)? В визуальной студии я могу просто щелкнуть правой кнопкой мыши и сделать «Получить последний», и он заканчивает моменты после. Я хочу иметь возможность сделать это автоматически. Спасибо, что помог btw! – KallDrexx

2

Работает ли такая же команда/параметры при использовании средств командной строки TFS? например TF.exe get?

У вас установлено антивирусное ПО? Возможно ли, что это мешает? Попробуйте временно отключить его.

Вы также можете включить TFS Client-Side трассировку в вашем app.config, чтобы увидеть, что происходит по проводам: http://blogs.msdn.com/b/edhintz/archive/2007/03/30/tfs-client-tracing.aspx

+0

Отличная ссылка. Я отредактировал свое сообщение с тем, что я нашел из файлов журнала, так как я еще больше запутался в том, что происходит, чем раньше. – KallDrexx

+1

На самом деле он повесил трубку на считыватель потока. Это никогда не возвращается из DownloadFile. – Robaticus

0

После является рабочим примером, с помощью которого вы можете получить последнюю версию кода с пути сервера

var status = workspace.Get(new GetRequest("$/XXXX/Development/Subfolder/", 
      RecursionType.Full, VersionSpec.Latest), 
      GetOptions.GetAll| GetOptions.Overwrite); 
Смежные вопросы