2010-02-26 78 views
1

我有一個MFC應用程序。它基本上只是將文件從一個驅動器複製到另一個。當我複製大文件(超過1 GB)時,我點擊我的窗口,我的應用程序凍結,但複製在後臺進行。有人告訴我,我必須使用工作線程。我用它,但它仍然凍結。當我複製小文件時,它是可以的。我無法弄清楚可能是什麼問題。請有人幫忙!當我複製大文件時,爲什麼我的應用程序會凍結?

這裏是我的代碼:

void CGetFileListDlg::OnBnClickedButtonGetFileList() 
{ 
//here i'm doing file list comparing 
AfxBeginThread(CopyThread, &Tstruct); //here i call my thread and give a struct to it as a paramter, which contains, which file i have to copy 
} 

UINT CopyThread(LPVOID pParam) 
{ 
UINT uiMaxPass = 3; 
UINT uiPAssCount = 0; 
int i = 0; 

threadstruct *Test = (threadstruct*)(pParam); 
CGetFileListDlg* ptr = (CGetFileListDlg*)Test->ez ; 

struct address 
{ 
    char *from; 
    char *to; 
    int current; 
}; 

struct address Address; 


for (i = 0; i < Test->diff; i++) 
    { 

    TCHAR currentfile[512], file[MAX_PATH +32], successf[10], unsuccessf[10], buf[20], remainingf[20], oprog[10]; 
    char tmp[1024], tmp2[1024],dest[1024]; 
    int j,k,l; 
    char ch; 

    memset(tmp, 0, sizeof(tmp)); 
    memset(dest, 0, sizeof(dest)); 
    memset(tmp2, 0, sizeof(tmp2)); 
    memset(buf, 0, sizeof(buf)); 
    memset(currentfile, 0, sizeof(currentfile)); 
    memset(file, 0, sizeof(file)); 
    memset(successf, 0, sizeof(successf)); 
    memset(unsuccessf, 0, sizeof(unsuccessf)); 
    memset(remainingf, 0, sizeof(remainingf)); 
    memset(oprog, 0, sizeof(oprog)); 
    ch = NULL; 
    strcat(dest, SecondaryHDD); 

    l = 1; 
    for (k = strlen(SecondaryHDD); k < strlen(Test->difference[i].filename); k++) 
    { 
     dest[k] = Test->difference[i].filename[ l + strlen(SecondaryHDD) - 1 ]; 
     l++; 
    } 
    dest[k]='\0'; 

    for (j = strlen(Test->difference[i].filename); ch != '\\'; j--) 
    { 
     ch = Test->difference[i].filename[j]; 
    } 

    l = 0; 
    for (k = 3; k < j + 1; k++) 
    { 
     tmp2[l] = Test->difference[i].filename[k]; 
     l++; 
    } 
    tmp2[l]='\0'; 
    strcpy(tmp, SecondaryHDD); 
    strcat(tmp, tmp2); 

    SHCreateDirectoryExA(NULL, tmp, NULL); 

    memset(file, 0, sizeof(file)); 

    memset(tmp, 0, sizeof(tmp)); 
    strcpy(tmp, Test->difference[i].filename); 

    MultiByteToWideChar( CP_ACP, NULL, tmp, -1, file, strlen(Test->difference[i].filename)); 
    wsprintf(currentfile, _T("%s"), file); 
    ptr->m_edCurrentCopy.SetWindowText(currentfile); 

    Address.from = strdup(tmp); 
    Address.to = strdup(dest); 
    Address.current = i; 

    PostMessage((HWND)Test->hWnd , WMU_PROGRESS, (WPARAM)&Address, (LPARAM)&dest); //calling OnProgressMsg function, which does the copy 
    Sleep(100); 
} 

PostMessage((HWND)Test->hWnd, WMU_COPYDONE, uiPAssCount, 0); 

return 0; 
} 

LRESULT CGetFileListDlg::OnProgressMsg(WPARAM wParam, LPARAM lParam) 
{ 
    TCHAR currentfile[512], file[MAX_PATH +32], successf[10], unsuccessf[10], buf[20], remainingf[20], oprog[10]; 
char tmp[1024], tmp2[1024],dest[1024]; 
int j,k,l; 
char ch; 
struct address 
{ 
    char *from; 
    char *to; 
    int current; 
}; 

address *Address = (address*)wParam; 

//char *to = (char*)lParam;  
//char *from = (char*)wParam;  

int ret = 0; 
ret = CopyFileA(Address->from, Address->to, false); 
//ret = CopyFileExA(Address->from, Address->to, &MyCopyProgressRoutine, this, FALSE,FALSE); 

if (ret == 0) //failed 
{ 
    wsprintf(buf, _T("Failed (%d)"), GetLastError()); 
    m_difference.SetItemText(Address->current, 2, buf); 
    unsuccess++; 
    wsprintf(unsuccessf, _T("%d"), unsuccess, GetLastError()); 
    m_unsuccess.SetWindowText(unsuccessf); 
} 
else 
{ 
    m_difference.SetItemText(Address->current, 2, L"OK!"); 
    success++; 
    wsprintf(successf, _T("%d"), success); 
    m_success.SetWindowText(successf); 
} 

wsprintf(remainingf, _T("%d"), (diff - (success + unsuccess))); 
m_remaining.SetWindowText(remainingf); 

wsprintf(oprog, _T("%d %%"), ((success + unsuccess) *100)/diff); 
m_overallprog.SetWindowText(oprog); 

UpdateData(FALSE); 

return 0; 
} 

回答

10
PostMessage((HWND)Test->hWnd , WMU_PROGRESS, (WPARAM)&Address, (LPARAM)&dest); 
//calling OnProgressMsg function, which does the copy 

因此,你生成一個新的線程,那...將消息發佈到主線程並獲取主線程來完成所有的複製?

這就是不是你如何使用工作線程。您的工作線程應該是進行復制的人員,並且所有OnProgressMsg應該做的就是更新UI。

+0

嗨!如果我正確理解你,比在我的CopyThread函數,我應該做的複製,並在OnProgressMsg函數我應該只是更新圖形用戶界面?我對嗎? – kampi 2010-02-26 02:07:29

+0

@ kampi:是的。就是這樣。 – 2010-02-26 02:11:49

+0

哦,夥計!非常感謝你!這是我的問題。現在它工作正常:)再次謝謝:) – kampi 2010-02-26 03:17:05

1

我想通過使用指的WorkerThread是,的WorkerThread必須做的複製。至少就Win32API而言,所有的Windows,實際上任何Windows中的hWnd句柄,都有一個消息循環。當此消息循環在足夠的時間內停止響應時,Windows資源管理器認爲您的應用程序「沒有響應」,因爲實際上它不是 - 它不處理消息。

你需要做的是調用複製的子線程,然後通知「父」線程完成後可以關閉對話框;或通知父對話框的進度,以便父對話框可以更新進度條,或類似的東西。

相關問題