I have a C# program which queries a database (server3) to determine the files a user is after, then copies those files from (server1) to (server2).
To simplify that further
When I run this program on my desktop, everything works fine except server1, which seems to almost grind to a holt after about 5 minutes, even though the copying process continues working fine even after 5 minutes. Any other application/user who try to connect to that server can't.
They just get a spinning cursor which only stops if I stop running the program on my desktop. For the first 5 minutes into the copying process, everything is fine for everyone. When going beyond the 5 minute range, the files continue to copy, but that's when others start experiencing connection problems to server1.
I have even tried using sleep as I assumed that the slow down was because of too much network activity and/or too much disk I/O activity on server1. sleep did nothing to help, the same problem continues. So I'm guessing the problem is happening for some other reason.
I am using code similar to this to copy the files
while (reader1.read(){
// system.threading.thread.sleep(2000);
system.io.file.copy(source, destination);
}
Why is this happening?
According to this article, the main cause of the slowdown is the use of buffering by the file copy.
On Windows Vista or later, it's possible to avoid using buffering by specifying COPY_FILE_NO_BUFFERING to the CopyFileEx() Windows API function.
You can specify the P/Invoke as follows:
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 (substituting your own file names);
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 trying this and seeing if it helps.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With