Server slowdown when copying files

I have a C # program that queries a database (server3) to determine the files the user is executing, and then copies those files from (server1) to (server2).

To simplify this,

  • A C # application runs on a desktop computer.
  • Source files are on server1
  • Files must be copied to server2
  • Server 3 contains the database

When I run this program on my desktop everything works fine except for server1, which seems to almost grind to holat after about 5 minutes, although the copy process continues to work fine even after 5 minutes. Any other application / user trying to connect to this server cannot.

They just get a spinning cursor that only stops if I stop running the program on my desktop. The first 5 minutes of the copying process is good for everyone. After going beyond 5 minutes, the files continue to copy, but when others start to experience problems connecting to the server.

I even tried using sleep

it as I assumed the slowdown was caused by too much network activity and / or too much I / O on server1. sleep

nothing helped, same problem continues. So I guess the problem is happening for a different reason.

I am using code like this to copy files

while (reader1.read(){
    // system.threading.thread.sleep(2000);
    system.io.file.copy(source, destination);
}

      

Why is this happening?

+3


source to share


1 answer


According to this article , the main reason for the slowdown is the use of file copy buffering.

In Windows Vista or later, you can avoid the use of buffering, pointing COPY_FILE_NO_BUFFERING

to the CopyFileEx()

Windows API function
.

You can specify P / Invoke like this:

enum CopyProgressResult: uint
{
    PROGRESS_CONTINUE = 0,
    PROGRESS_CANCEL   = 1,
    PROGRESS_STOP     = 2,
    PROGRESS_QUIET    = 3
}

enum CopyProgressCallbackReason: uint
{
    CALLBACK_CHUNK_FINISHED = 0x00000000,
    CALLBACK_STREAM_SWITCH  = 0x00000001
}

delegate CopyProgressResult CopyProgressRoutine(
    long TotalFileSize,
    long TotalBytesTransferred,
    long StreamSize,
    long StreamBytesTransferred,
    uint dwStreamNumber,
    CopyProgressCallbackReason dwCallbackReason,
    IntPtr hSourceFile,
    IntPtr hDestinationFile,
    IntPtr lpData);

[Flags]
enum CopyFileFlags: uint
{
    COPY_FILE_FAIL_IF_EXISTS              = 0x00000001,
    COPY_FILE_RESTARTABLE                 = 0x00000002,
    COPY_FILE_OPEN_SOURCE_FOR_WRITE       = 0x00000004,
    COPY_FILE_ALLOW_DECRYPTED_DESTINATION = 0x00000008,
    COPY_FILE_COPY_SYMLINK                = 0x00000800, //NT 6.0+
    COPY_FILE_NO_BUFFERING                = 0x00001000
}

[DllImport("kernel32.dll", SetLastError=true, CharSet=CharSet.Auto)]
[return: MarshalAs(UnmanagedType.Bool)]
static extern bool CopyFileEx
(
    string lpExistingFileName,
    string lpNewFileName,
    CopyProgressRoutine lpProgressRoutine, 
    IntPtr lpData,
    ref Int32 pbCancel,
    CopyFileFlags dwCopyFlags
);

      



Then call it like this (replace your own filenames);

int cancel = 0;
CopyFileEx(@"C:\tmp\test.bin", @"F:\test.bin", null, IntPtr.Zero, ref cancel, CopyFileFlags.COPY_FILE_NO_BUFFERING);

      

It might be worth giving it a try and see if that helps.

+2


source







All Articles