2014-09-24 48 views
3

我有一個C#程序查詢數據庫(server3)以確定用戶所處的文件,然後將這些文件從(server1)複製到(server2)。複製文件時服務器變慢

爲了簡化進一步

  • C#應用程序在桌面計算機
  • 原始文件在Server1上執行
  • 文件將被複制到Server2
  • Server3的包含數據庫

當我在我的桌面上運行這個程序時,一切正常,除了server1,這似乎almos即使5分鐘後複印過程仍能繼續良好地工作,但大約5分鐘後仍會磨成碎片。任何其他嘗試連接到該服務器的應用程序/用戶都不能。

他們只是得到一個旋轉的光標,只有當我停止在我的桌面上運行程序時才停止。對於複製過程的前5分鐘,每個人都可以。當超出5分鐘的範圍時,文件會繼續複製,但是當別人開始遇到與server1的連接問題時。

我甚至嘗試過使用sleep,因爲我認爲減速是因爲網絡活動過多和/或server1上的磁盤I/O活動過多。 sleep沒有任何幫助,同樣的問題仍然存在。所以我猜猜這個問題是出於其他原因。

我使用類似下面的代碼複製文件

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

這究竟是爲什麼?

+0

如何複製文件?如果你只是在做一堆連續的文件副本,聽起來就像你的服務器只是不足夠的。如果你想要並行運行多個副本,那麼你應該把你的代碼構造成不那麼激進。 – 2014-09-24 11:47:33

+0

我正在複製基於數據庫查詢的特定文件。不是平行復制,它一次複製1個文件。 – oshirowanen 2014-09-24 11:48:06

+0

這不能回答我的問題。你能顯示一些代碼嗎? – 2014-09-24 11:48:36

回答

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); 

這可能值得嘗試一下,看看它是否有幫助。

+0

@oshirowanen它只是想在前一行定義一個'int cancel = 0;'。(我會更新示例) – 2014-09-25 10:59:50

+0

代碼正在工作,但仍然會導致原始問題,即大約5分鐘後,需要server1的所有應用程序/用戶開始放慢速度,直到我停止從桌面運行復制應用程序。 – oshirowanen 2014-09-25 11:18:58

+0

@oshirowanen嗯,這是值得一試。您是否閱讀過我在答覆開始時引用的文章 - 它確實提出了其他一些內容。 – 2014-09-25 12:03:54

相關問題