none
Why is .NET's File.Open with a UNC path making excessive SMB requests? RRS feed

  • Question

  • I have a block of code that needs to open and read a lot of small text files from a NAS server using UNC paths.  This code is part of a module that was originally written in C++ but is now being converted to C#.  The C# version is significantly slower.  I determined that the call to open the file accounts for nearly all of the performance difference.  Using WireShark I found that this is because the System.IO.File.Open call makes far more SMB network requests than similar C++ code.

    The C++ code makes this call:

    FILE *f = _wfsopen(fileName, L"r", _SH_DENYWR);

    This results in the following sequence of SMB requests:

    NT Create AndX Request, FID: 0x0004, Path: \\a\\i\\a\\q\\~141106162638847.nmd
    NT Create AndX Response, FID: 0x0004
    Trans2 Request, QUERY_FILE_INFO, FID: 0x0004, Query File Basic Info
    Trans2 Response, FID: 0x0004, QUERY_FILE_INFO
    Read AndX Request, FID: 0x0004, 1327 bytes at offset 0
    Read AndX Response, FID: 0x0004, 1327 bytes
    Close Request, FID: 0x0004
    Close Response, FID: 0x0004
    NT Create AndX Request, FID: 0x0005, Path: \\a\\i\\a\\q\\~141106162638847.nmd
    NT Create AndX Response, FID: 0x0005

    The C# code makes this call:

    FileStream f = File.Open(fileName, FileMode.Open, FileAccess.Read, FileShare.Read);

    This results in the following sequence of SMB requests:

    Trans2 Request, QUERY_PATH_INFO, Query File Basic Info, Path: \\a\\i\\a\\q\\~141106162638847.nmd
    Trans2 Response, QUERY_PATH_INFO
    Trans2 Request, QUERY_PATH_INFO, Query File Standard Info, Path: \\a\\i\\a\\q\\~141106162638847.nmd
    Trans2 Response, QUERY_PATH_INFO
    Trans2 Request, QUERY_PATH_INFO, Query File Basic Info, Path: \\a\\i\\a\\q\\~141106162638847.nmd
    Trans2 Response, QUERY_PATH_INFO
    Trans2 Request, QUERY_PATH_INFO, Query File Basic Info, Path: 
    Trans2 Response, QUERY_PATH_INFO
    Trans2 Request, QUERY_PATH_INFO, Query File Standard Info, Path: 
    Trans2 Response, QUERY_PATH_INFO
    Trans2 Request, FIND_FIRST2, Pattern: \\a
    Trans2 Response, FIND_FIRST2, Files: a
    Trans2 Request, QUERY_PATH_INFO, Query File Basic Info, Path: \\a
    Trans2 Response, QUERY_PATH_INFO
    Trans2 Request, QUERY_PATH_INFO, Query File Standard Info, Path: \\a
    Trans2 Response, QUERY_PATH_INFO
    Trans2 Request, FIND_FIRST2, Pattern: \\a\\i
    Trans2 Response, FIND_FIRST2, Files: i
    Trans2 Request, QUERY_PATH_INFO, Query File Basic Info, Path: \\a\\i
    Trans2 Response, QUERY_PATH_INFO
    Trans2 Request, QUERY_PATH_INFO, Query File Standard Info, Path: \\a\\i
    Trans2 Response, QUERY_PATH_INFO
    Trans2 Request, FIND_FIRST2, Pattern: \\a\\i\\a
    Trans2 Response, FIND_FIRST2, Files: a
    Trans2 Request, QUERY_PATH_INFO, Query File Basic Info, Path: \\a\\i\\a
    Trans2 Response, QUERY_PATH_INFO
    Trans2 Request, QUERY_PATH_INFO, Query File Standard Info, Path: \\a\\i\\a
    Trans2 Response, QUERY_PATH_INFO
    Trans2 Request, FIND_FIRST2, Pattern: \\a\\i\\a\\q
    Trans2 Response, FIND_FIRST2, Files: q
    Trans2 Request, QUERY_PATH_INFO, Query File Basic Info, Path: \\a\\i\\a\\q\\~141106162638847.nmd
    Trans2 Response, QUERY_PATH_INFO
    Trans2 Request, QUERY_PATH_INFO, Query File Standard Info, Path: \\a\\i\\a\\q\\~141106162638847.nmd
    Trans2 Response, QUERY_PATH_INFO
    Trans2 Request, QUERY_PATH_INFO, Query File Basic Info, Path: \\a\\i\\a\\q\\~141106162638847.nmd
    Trans2 Response, QUERY_PATH_INFO
    Trans2 Request, QUERY_PATH_INFO, Query File Basic Info, Path: 
    Trans2 Response, QUERY_PATH_INFO
    Trans2 Request, QUERY_PATH_INFO, Query File Standard Info, Path: 
    Trans2 Response, QUERY_PATH_INFO
    Trans2 Request, FIND_FIRST2, Pattern: \\a
    Trans2 Response, FIND_FIRST2, Files: a
    Trans2 Request, QUERY_PATH_INFO, Query File Basic Info, Path: \\a
    Trans2 Response, QUERY_PATH_INFO
    Trans2 Request, QUERY_PATH_INFO, Query File Standard Info, Path: \\a
    Trans2 Response, QUERY_PATH_INFO
    Trans2 Request, FIND_FIRST2, Pattern: \\a\\i
    Trans2 Response, FIND_FIRST2, Files: i
    Trans2 Request, QUERY_PATH_INFO, Query File Basic Info, Path: \\a\\i
    Trans2 Response, QUERY_PATH_INFO
    Trans2 Request, QUERY_PATH_INFO, Query File Standard Info, Path: \\a\\i
    Trans2 Response, QUERY_PATH_INFO
    Trans2 Request, FIND_FIRST2, Pattern: \\a\\i\\a
    Trans2 Response, FIND_FIRST2, Files: a
    Trans2 Request, QUERY_PATH_INFO, Query File Basic Info, Path: \\a\\i\\a
    Trans2 Response, QUERY_PATH_INFO
    Trans2 Request, QUERY_PATH_INFO, Query File Standard Info, Path: \\a\\i\\a
    Trans2 Response, QUERY_PATH_INFO
    Trans2 Request, FIND_FIRST2, Pattern: \\a\\i\\a\\q
    Trans2 Response, FIND_FIRST2, Files: q
    Close Request, FID: 0x000f
    Close Response
    NT Create AndX Request, FID: 0x0018, Path: \\a\\i\\a\\q\\~141106162638847.nmd
    NT Create AndX Response, FID: 0x0018
    Trans2 Request, QUERY_FILE_INFO, FID: 0x0018, Query File Basic Info
    Trans2 Response, FID: 0x0018, QUERY_FILE_INFO
    Read AndX Request, FID: 0x0018, 1327 bytes at offset 0
    Read AndX Response, FID: 0x0018, 1327 bytes
    Close Request, FID: 0x0018
    Close Response, FID: 0x0018
    NT Create AndX Request, FID: 0x0019, Path: \\a\\i\\a\\q\\~141106162638847.nmd
    NT Create AndX Response, FID: 0x0019

    Why does System.IO.File.Open make all these extra SMB requests?  Is there any way to change this code to avoid all these extra requests?

    Wednesday, November 26, 2014 5:38 PM

All replies

  • Hello BradVoy,

    >>Why does System.IO.File.Open make all these extra SMB requests?  Is there any way to change this code to avoid all these extra requests?

    In my opinion, for this managed method, I think this should be by designed and it does some extra works inside it so that it would make all these extra SMB requests.

    If you do not want to see these extra SMB requests, one workaround is to wrap your original C++ method to a dll and call it in C# code using P/Invoke way:

    http://msdn.microsoft.com/en-us/library/aa288468(v=vs.71).aspx

    Regards.


    We are trying to better understand customer views on social support experience, so your participation in this interview project would be greatly appreciated if you have time. Thanks for helping make community forums a great place.
    Click HERE to participate the survey.

    • Marked as answer by Fred BaoModerator Monday, December 8, 2014 5:17 AM
    • Unmarked as answer by BradVoy Monday, December 8, 2014 2:50 PM
    Thursday, November 27, 2014 2:50 AM
    Moderator
  • I realize that System.IO.File.Open is doing extra work.  My question is whether there is a way, via code or configuration, to make it skip that extra work and just open the file.

    I know I can call C++ code from .NET using P/Invoke or COM Interop.  But my goal was to eliminate the C++ code. 

    Monday, December 8, 2014 8:21 PM
  • Hello BradVoy,

    Not sure if we can skip that extra work since the .NET method is different implemented from the method of C++, for this issue, I am trying to invoke someone experienced to help look into this, it may take some time and as soon as we get any result, we will post back to this forum.

    Regards.


    We are trying to better understand customer views on social support experience, so your participation in this interview project would be greatly appreciated if you have time. Thanks for helping make community forums a great place.
    Click HERE to participate the survey.

    Tuesday, December 9, 2014 7:37 AM
    Moderator