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?
source to share
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.
source to share