none
Team Foundation Server: Initial Get takes longer than get in TF.EXE RRS feed

  • Question

  • I'm downloading files with this code:

    TfsTeamProjectCollection tfsTeamProjectCollection 
        = new TfsTeamProjectCollection(new Uri("http://local.DevOps-TFS/tfs/resourceCollection"));
    
    Workspace ws 
        = Workstation.Current.GetAllLocalWorkspaceInfo()[0].GetWorkspace(tfsTeamProjectCollection);
    
    Stopwatch s = new Stopwatch();
    s.Start();
    ws.Get(new string[] { "$/REPO/file.cpp" }, VersionSpec.Latest, RecursionType.OneLevel, GetOptions.GetAll);
    s.Stop();
    Console.WriteLine(s.Elapsed.TotalSeconds);
    
    Stopwatch s = new Stopwatch();
    s.Start();
    ws.Get(new string[] { "$/REPO/file2.cpp" }, VersionSpec.Latest, RecursionType.OneLevel, GetOptions.GetAll);
    s.Stop();
    Console.WriteLine(s.Elapsed.TotalSeconds);

    This works well, except that the first GET takes 9 seconds, the 2nd get takes 0.05 seconds. It doesn't matter what files and how many I'm getting, the first file ALWAYS takes significantly longer than the following gets.

    The weird thing is: getting the file with the TF.exe works way faster, the first get is as fast as the other ones.

    tf vc get $/REPO/file.cpp /force

    I've debugged into the TFS-API Source-code and the problem is the moment the API waits for the rest-api call to finish. I assume that there's a problem with the authentication, but I couldn't figure out what exactly is wrong. I've also debugged into the TF.exe to see how they authenticate, but I didn't find anything specific and they're using the same code as above. But somehow the rest-api call started from the TF.exe finished much faster than the rest-api call from my application.

    We're using TFS version 16. Any suggestions on how to continue?


    • Edited by null_X Monday, September 30, 2019 8:20 AM
    Monday, September 30, 2019 8:18 AM

All replies

  • The client you're using is woefully outdated and not really getting any support anymore. You should be using the newer REST clients unless you're explicitly targeting a legacy version of TFS. The newer APIs are faster in my experience. You will still take a hit when you authenticate the first time, there is no way around that but 8.5 seconds isn't authentication. I migrated half a TB worth of source files (along with all the work items, branches, users, queries, etc) from on premise to Azure in a weekend using the REST API. Authentication happens with the dedicated credentials you are using so it is minimal compared to everything else. 

    As an example of how you might use it to read from TFS (TFVC) and/or write (Git) you can refer to the source code I posted. You should be able to download an entire TFVC project in a matter of seconds unless it is 1000s of files.

    You're using workspaces though and that isn't something that the REST API can do. However I notice that you're just setting up the workspace to download files and then you download specific files from the root project. So in the REST API you wouldn't need to do the workspace thing.

    Alternatively if it is an authentication problem then call `Authenticate` on the collection object before you try to get the files. This should eliminate the authentication part.


    Michael Taylor http://www.michaeltaylorp3.net

    Monday, September 30, 2019 2:05 PM
    Moderator
  • Thanks for your answer!

    I've used .Authenticate but it still takes the same amount of time, I've removed it in my example because that's the way the TF.exe handles it. The workspace is needed because the GET is not the only functionality we use (checkout, undo, checkin...)

    Downloading the files works fine on the second try, it takes about 50 seconds for 20000 files which is amazing, but I still don't understand why the first try doesn't work as good. The TF.exe also uses the workspace to get files and yet still is faster on the first try. 

    What comes into my mind is that the workspace is set up using the TF.exe when connecting to a server, so maybe the authentication is done way before and is being cached - which doesn't happen in my application because it's seemingly 'always a new connection'. I'll check on that and reply if I can find anything.

    Tuesday, October 1, 2019 7:02 AM