2014-09-24 8 views
3

데이터베이스 (server3)를 쿼리하여 사용자가있는 파일을 확인한 다음 해당 파일을 (server1)에서 (server2)로 복사하는 C# 프로그램이 있습니다.파일 복사시 서버 속도 저하

가 더

  • C# 응용 프로그램을 단순화하기 위해
  • 파일이 서버 2에 복사 할 수 있습니다
  • 원본 파일이 서버 1에있는 데스크톱 컴퓨터에서 실행되는
  • Server3을 데이터베이스를 포함

바탕 화면에서이 프로그램을 실행하면 almos처럼 보이는 server1을 제외하고 모두 제대로 작동합니다. 복사 프로세스가 5 분 후에도 계속 잘 작동하더라도 약 5 분 후에 홀트로 연마됩니다. 해당 서버에 연결하려는 다른 응용 프로그램/사용자는 할 수 없습니다.

데스크톱에서 프로그램 실행을 중단하면 멈추는 회전 커서가 생깁니다. 복사 과정의 처음 5 분 동안 모든 것이 모든 사람에게 좋습니다. 5 분 범위를 벗어나면 파일은 계속 복사되지만 다른 사람이 server1에 대한 연결 문제가 발생하기 시작하면됩니다.

심지어 slow32가 너무 많은 네트워크 활동 및/또는 너무 많은 디스크 I/O 활동으로 인해 server1에 있다고 가정하기 때문에 sleep을 사용해 보았습니다. sleep도 도움이되지 않았지만 동일한 문제가 계속 발생합니다. 그래서 저는 다른 어떤 이유로이 문제가 발생하고 있다고 생각합니다.

내가 파일

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

왜 이런 일이 복사하려면이 유사한 코드를 사용하고

?

+0

파일을 어떻게 복사하고 있습니까? 순차적 인 파일 사본을 여러 개 만들면 서버가 제대로 작동하지 않는 것처럼 들립니다. 병렬로 많은 복사본을 실행하려는 경우 코드를 구조화하여 덜 공격적으로 구성해야합니다. –

+0

데이터베이스 쿼리를 기반으로 특정 파일을 복사하고 있습니다. 병렬 복사가 아니라 한 번에 한 파일 씩 복사합니다. – oshirowanen

+0

그건 내 질문에 대답하지 않습니다. 몇 가지 코드를 보여줄 수 있습니까? –

답변

2

this article,에 따르면 속도 저하의 주요 원인은 파일 복사에 의한 버퍼링 사용입니다.

Windows Vista 이상에서는 COPY_FILE_NO_BUFFERINGCopyFileEx() Windows API function으로 지정하여 버퍼링을 사용하지 않아도됩니다.

당신은 P를 지정할 수/호출은 다음과 같이

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;'이 선행에 정의되기를 원할 뿐이다.(샘플 업데이트) –

+0

코드가 작동하지만 원래 문제가 발생합니다. 약 5 분 후 server1이 필요한 모든 앱/사용자는 데스크톱에서 복사 애플리케이션 실행을 중지 할 때까지 속도가 느려집니다. – oshirowanen

+0

@oshirowanen 아, 그럴 가치가있었습니다. 제 대답을 시작할 때 인용 한 기사를 읽으셨습니까? 다른 것들을 제안합니다. –