我有一个C#程序,它查询数据库(server3)以确定用户所在的文件,然后将这些文件从(server1)复制到(server2)。
进一步简化
当我在桌面上运行这个程序时,一切正常,除了server1,即使复制过程在5分钟后继续正常工作,它似乎在大约5分钟之后几乎磨成了hol。尝试连接到该服务器的任何其他应用程序/用户都可以
他们只是得到一个旋转光标,只有当我停止在桌面上运行程序时才会停止。在复制过程的前5分钟,一切都很好。当超过5分钟范围时,文件将继续复制,但是当其他人开始遇到与server1的连接问题时。
我甚至尝试使用sleep
,因为我认为减速是因为网络活动过多和/或server1上的磁盘I / O活动过多。 sleep
没有任何帮助,同样的问题还在继续。所以我猜测问题是由于其他原因而发生的。
我正在使用与此类似的代码来复制文件
while (reader1.read(){
// system.threading.thread.sleep(2000);
system.io.file.copy(source, destination);
}
为什么会这样?
答案 0 :(得分:2)
根据this article,,减速的主要原因是文件副本使用缓冲。
在Windows Vista或更高版本中,通过将COPY_FILE_NO_BUFFERING
指定给CopyFileEx()
Windows API function,可以避免使用缓冲。
您可以按如下方式指定P / Invoke:
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
);
然后像这样调用它(替换你自己的文件名);
int cancel = 0;
CopyFileEx(@"C:\tmp\test.bin", @"F:\test.bin", null, IntPtr.Zero, ref cancel, CopyFileFlags.COPY_FILE_NO_BUFFERING);
尝试这个并看看它是否有帮助可能是值得的。